“Paradigm Shift”: My Journey with ‘Domain Modeling Made Functional’ and the Shift to Functional Programming
As a programmer, I’m always on the lookout for fresh perspectives that challenge the status quo. Late in 2021, I stumbled upon a guidebook of sorts, the Domain Modeling Made Functional: Tackle Software Complexity with Domain-Driven Design and F#. The presence of “Domain Driven Design” in the title was what mainly drew me to it. I had already read the classics on this subject: the “Blue Book”, the “Red Book” and also “Learning Domain-Driven Design”, along with a few projects whose complexity definitely justified a domain-driven modeling approach. I was counting on a fresh perspective on DDD being a cool experience.
The book introduces, in a friendly manner, topics related to both functional programming and domain-focused design. Surprisingly, I found myself more intrigued by the aspects of the new-to-me functional approach to coding. The shift from imperative to declarative, the way it was presented in the book, sparked something. There was one of those “a-ha” moments :).
I started experimenting with this newfound approach in my work with C#, looking for resources on functional programming in this language. I read Functional Programming in C#, Second Edition, and became familiar with CSharpFunctionalExtensions.
The code became simpler, cyclomatic complexity decreased.
However, despite the fact that over the years, more and more functional elements from F# have been appearing in the successive versions of C#, trying to stick to a functional approach in C# still required a bit of extra work and reminded me of trying to swim against the current.
Intrigued, I decided to take a closer look at F#. Two fantastic books later (Essential F# and Stylish F# 6), I was already in love with the simplicity and readability it offered. Plus, as part of the .NET ecosystem, it fit perfectly into the set of tools we at Open Clue use to deliver solutions to our clients.
Thanks to our emphasis on identifying (discovering) subdomains when designing our solutions, which we then define in the form of bounded contexts, I was able to safely test the use of F# initially in small, non-core, and above all, autonomous services.
It worked out great 🙂
After gaining some experience in functional programming, I decided to return to the book that’s the topic of this post. Re-reading it allowed me to fully appreciate the potential of combining the functional paradigm with Domain Driven Design.
Documenting requirements in the form of (almost) pure F# code, involving a domain expert. Composing complex business rules from simpler functions, like Lego blocks. Significantly simpler testing, mainly focusing on outcome-based testing. The error handling approach in logic using “Railway oriented programming” combined with computational expressions allowed for the implementation of a simple, transparent, yet secure data flow.
These are just some of the advantages of the approach presented in the book.
Some topics, by necessity, were covered briefly (Persistence, Event sourcing, CQRS), but sufficiently so that the reader could delve into these concepts in a functional context on their own.
A necessary addition is the code repository containing the complete code, fragments of which are presented in the book.
To sum up, the book by Scott Wlaschin not only enriched my knowledge about DDD, but above all, introduced me to a whole new world of functional programming.
There are many great books in the IT field, but only a few of them really change the way we think about our craft. For me, Scott’s book is just such a position, standing next to Clean Code, Domain-Driven Design: Tackling Complexity in the Heart of Software or Programmers Brain (a real gem).
I highly recommend reading it, at least twice :-).
P.S. It’s also worth mentioning that Scott Wlaschin is the author of a real wellspring of knowledge about F#: fsharpforfunandprofit.com – it’s impossible to overestimate the materials available there.