Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
The Limits of Functional Programming: Performance, Readability and Pragmatic Team Use
The cost of functional programming in C# is usually not where people expect: measured, LINQ is nanoseconds slower than a loop for a small cart, Option's cost comes from closures more than from being a struct or a class, and carrying expected errors as exceptions is a hundred times more expensive than Result. We show the BenchmarkDotNet results, stack traces in composition, which ideas pay off in a team, F#, and where Bookstore ended up.
C# 15 Union Types and Closed Hierarchies: Real Sum Types and Exhaustive Pattern Matching
C# 15 union types combine independent types into a closed set, and the closed modifier limits the direct subtypes of a class hierarchy to its assembly; in both cases the compiler names the missing case. We turn Bookstore's OrderStatus into a closed hierarchy and Result and its error codes into unions, and show how System.Text.Json serializes each, how they compare with TypeScript, and the binary breaking change risk in a public API, all with real output.
Result and Railway-Oriented Programming: Errors as Values and Accumulating Validation
Railway-oriented programming connects steps that can fail into a two-track flow with Bind: if a step fails, later steps don't run and the error is carried to the end as a value, while errors from independent form fields are accumulated. We build Bookstore's order flow with Map, Bind, Ensure, Tap and Match, and show Task<Result<T>> chains, mapping to TypedResults and ValidationProblem, the Angular UI state and the line between exceptions and Result, all with real output.
Option and Escaping Null: the Maybe Type, Map, Bind and the Secret of LINQ Query Syntax
Option expresses "no value" as a type and makes you answer "what if there isn't one?" before you reach the value; nullable reference types are enough in most places, but Option pays off in chained computations and nested kinds of absence. We build Bookstore's coupon calculation with our own Option<T> using Map, Bind and Match, and show why LINQ query syntax works once Select/SelectMany exist, along with the map + flatten intuition behind monads.
Algebraic Data Types: Product and Sum Types, Discriminated Unions and Making Illegal States Unrepresentable
Algebraic data types combine types with "and" (product types) or "or" (sum types) so that the number of combinations in the model equals the number of states in the business rule, making impossible states impossible to build. We turn Bookstore's flagged order status into a sum type with abstract records, write transitions with types, and show why C# 14 wants a _ arm, TypeScript discriminated unions, JSON polymorphism and C# 15 union types with real compiler output.
Higher-Order Functions and Composition: map/filter/reduce, Currying and Building Pipelines
A higher-order function takes or returns functions; composition connects them into a new function, and its order is a business rule. We combine Bookstore's coupon and member discount as Func<decimal, decimal> rules with Then, Compose and Pipe, test that the order changes the result by 1.50 TL, and show fold, currying, a TypeScript pipe and the cost of closure allocations with real output.
Pure Functions and Side Effects: Referential Transparency, Hidden Inputs and Testability
A pure function always gives the same result for the same input and leaves no trace outside; such a call can be replaced by its value. Starting from decimal.Parse reading 189.50 as 18950 under the Turkish culture, we separate Bookstore's discount calculation from the clock, the console and static state, test it with xUnit theories and no fakes, and show memoization and the purity assumption of Angular computed() and pure pipes with real output.
Immutability: Why Unchanging Data? record, readonly and TypeScript Readonly in Practice
Immutability means a value can't be changed after creation and every change produces a new value; it solves aliasing, lost cache keys and race conditions at the same point. We rewrite Bookstore's cart with record, with and ImmutableList, and show with real output shallow immutability, the cost of copying, the limits of TypeScript readonly and Object.freeze, and why an array pushed in place doesn't update an Angular signal.
What Is Functional Programming? Declarative Thinking for C# and TypeScript Developers
Functional programming means building a computation as a combination of functions that take and return values, rather than as commands that change values step by step. Using Bookstore's checkout code that silently changes the cart, we show the difference between imperative and declarative code, first-class functions, a short history and the functional ideas you already use in LINQ, RxJS and Angular signals, with real output.