What Is HomeAccounting?

The previous post was the why: eleven years of tracking household money, two tools that didn't survive, and one requirement left standing at the end — recording what you spend should cost no time at all.

This one is the what and the how. HomeAccounting is an open-source, free accounting system for households — AGPL-licensed, built in the open, and meant to be shaped by the people who use it, not just by me. First, what you can actually do with it today. Then the inside: how a transaction gets from a bank statement or a Telegram message to a balance, what happens when you correct one, and what running eventium in a real application taught me that the library's examples never did.

Why Did I Build HomeAccounting?

For eleven years I've been writing down what my household spends. One of those years was Excel. The other ten were 1C.

Neither tool survived. Both of them were right about something, and I didn't understand what until I'd lost them.

They also failed the same way, which took me most of those eleven years to see. Every tool I tried was fundamentally a form to fill in. They competed on what happened after the data was in — the reports, the charts, the budgets — and they all quietly agreed that getting it in was my job, in my evenings, forever. That's the bill that eventually goes unpaid. So the thing I actually set out to build wasn't a better ledger. It was one that costs no time at all.

Haskell for Scala Developers: Part 5 — Optics and Deriving

This is the least philosophical piece you could write comparing Haskell and Scala, and the one you'll reach for most often. It's about the two things you actually do every Tuesday afternoon. Reach into a deeply nested immutable value and change one field three levels down. And get a type's boilerplate — JSON, equality, the lenses themselves — written for you instead of by hand.

Both languages solve both problems, and — this is the through-line — both solve them the same way underneath: by generating code from the shape of your types. Scala reaches for a lens library (Monocle) built on macros, and for derives clauses backed by Mirror and, when that runs out, inline/quotes. Haskell reaches for the optics ecosystem and for a deriving mechanism sitting on GHC.Generics, with Template Haskell as the full-power back door. Two languages, the same two destinations, arriving by different roads.

Two threads run through it: the record-update pain that makes optics worth having, and the deriving story, where Haskell's DerivingVia has no Scala equivalent at all.

Haskell for Scala Developers: Part 4 — Objects and Modules

Here's a thesis worth defending: most of Scala's object-oriented machinery is answers to questions Haskell never asks. Inheritance, trait linearization, the five different places a definition can live, private and its dozen qualifiers — a large fraction of it exists to manage complexity that a language built on data and functions simply doesn't generate.

That's the spicy half. Here's the fair half. Four of the things OOP was actually solving are real problems: polymorphic dispatch, code reuse, modularity, and controlled mutation with encapsulation. Every language needs answers to those. The argument of this post is not that Haskell ignores them — it's that Haskell answers each with something smaller and more honest than a class hierarchy, and that the smaller answer is usually the better one. Where Scala's version earns its keep, I'll say so; there are two or three places it genuinely does.

One running example the whole way down: a notification service. It's the canonical OOP teaching object — a polymorphic send, a hierarchy of channels, mixins that add retry and rate-limiting, and a private counter tracking deliveries. If you've sat through an "intro to OOP" course you've written this exact class. We're going to watch it dissolve into a handful of data types and functions, and I'll argue that what's left is what you actually wanted.

Haskell for Scala Developers: Part 3 — Effects and Concurrency

IO is a Monad in both Scala and Haskell, and do { line <- getLine; putStrLn line } is the same shape as for { line <- IO.readLine; _ <- IO.println(line) } yield (). That equivalence is where this post starts — with the part of the language that made half the Scala community pick up Cats Effect in the first place.

Here's the thesis, stated plainly: Cats Effect's IO is Haskell's IO, ported to the JVM. Not "inspired by." Ported. The referential transparency, the lazy description-of-a-computation, the run-it-at-the-edge model, bracket, Ref, race, fibers — all of it is the Haskell IO programming model rebuilt on a runtime that wasn't designed for it. Once you delete Future from your mental model, the distance between a Cats Effect program and the equivalent Haskell program is mostly tooling and syntax.

ZIO is the one place that story gets more interesting, and it's why I asked to cover both. ZIO's ZIO[R, E, A] is a genuinely different bet — it folds the environment and the error type into the effect type itself. Haskell makes that same bet too, but it spreads the pieces across different tools: ReaderT for the R, ExceptT or plain exceptions for the E, and increasingly an effect-handler library (effectful, polysemy, fused-effects) when you want the whole thing in one place. Same problem, different decomposition, real trade-offs on both sides.

The map: why Future is the thing to delete, what IO-as-a-value buys you, how errors become just another effect, resource safety, shared state, structured concurrency with a worked example, and finally ZIO against Haskell's MTL. The one neighbor I'm leaving for its own post is streaming — fs2 and ZIO Streams against conduit and streamly is a comparison that deserves the room.