Blog

Articles, tutorials, and insights about functional programming in Java

Subscribe via RSS
Retry, Timeout, and Backoff as Composable Functions

Retry, Timeout, and Backoff as Composable Functions

Retry loops, timeouts, and backoff usually arrive as tangled imperative code or a heavy resilience framework. There is a lighter option: model each policy as a function that wraps a function. Once retry, timeout, and backoff are ordinary higher-order functions, they compose — and you can read a call's full resilience behavior in one line.

A Practical Learning Path for Functional Programming in Java

A Practical Learning Path for Functional Programming in Java

Most developers learn functional programming in the wrong order — starting with monads and category theory instead of the habits that actually change their code. This is a staged path that starts with pure functions and immutability, then adds types, then composition, building each skill on the one before it.

Vavr, Arrow, Cats, fp-ts: What Problems Do They Solve?

Vavr, Arrow, Cats, fp-ts: What Problems Do They Solve?

Four libraries, four languages, one recurring motivation. Vavr, Arrow, Cats, and fp-ts exist because mainstream languages gave developers functional building blocks but left out the types that make them safe. This post maps what each library actually provides — and what gap in the host language each one fills.

Pure Functions and Side Effects

Pure Functions and Side Effects

A pure function always returns the same output for the same input and changes nothing in the world around it. That single rule — predictable output, no hidden changes — is the foundation that makes functional code easier to test, reason about, and refactor.

Algebraic Data Types Explained for Business Software Developers

Algebraic Data Types Explained for Business Software Developers

Algebraic Data Types sounds like a math lecture. It is actually a simple idea with a large practical payoff: two building blocks — AND and OR — that let you model business domains so precisely that illegal states cannot be represented in code at all.

How to Model Data Transformation Pipelines

How to Model Data Transformation Pipelines

Ad-hoc transformation code grows into spaghetti because there is no shared vocabulary for what a stage is, what it produces, or how failures propagate. Functional types give you that vocabulary — typed stage boundaries, composable error handling, and batch pipelines that separate failures from successes without stopping the whole run.

Currying and Partial Application in Practice

Currying and Partial Application in Practice

Currying sounds like academic theory. Partial application is something Java developers already do every day — they just don't name it. This post names it, distinguishes the two concepts, and shows five situations where partial application makes real production code cleaner.

Designing More Expressive APIs with Functional Types

Designing More Expressive APIs with Functional Types

A method signature is a contract. Most Java APIs break that contract silently — returning null, throwing undeclared exceptions, or hiding multiple outcomes behind a boolean. Functional types turn vague promises into honest, self-documenting interfaces.

Do You Need a Functional Library or Just Better Habits?

Do You Need a Functional Library or Just Better Habits?

Adding a functional library to a Java codebase rarely solves the underlying problem on its own. Sometimes the library is the right answer. Sometimes the problem is discipline, naming, and design — and a library just gives bad habits a fancier vocabulary.