Functional Architecture Is Better
Wittgenstein wrote, “The limits of my language mean the limits of my world.”
Moritz Nähr, Public domain, via Wikimedia Commons
And functional architecture works best with functional programming languages.
Functional Software Architecture (“FUNAR”) is one of the most advanced curricula in the iSAQB Advanced canon. It’s about the specific techniques for domain modelling and structuring software systems that functional programming enables. These are significantly different from the convential techniques available in object-oriented architecture, and lead to significant improvements of important architecture quality metrics: They reduce coupling and complexity, the resulting models are more supple, and it is significantly easier to establish correctness.
How does functional architecture do this? The three most important factors are:
- immutable data
- powerful abstractions
What does all that mean specifically?
Immutable data means that the program does not alter objects after creation. There are no “setter methods”. At first, this sounds like a painful restriction compared to OO, not really like a feature: After all, changing objects is pretty much the basis for object-oriented programming. How can you model state without changing objects?
It turns out to be quite simple: In a functional architecture, when a new state comes into effect, the program does not mutate the object representing the state. Instead, it just creates a new one. The old one stays as it was, basically a memory of the past. Consequently, in functional programming, objects representing state are a kind of snapshot.
Not changing objects in place has many concrete advantages:
- The output of a function is solely determined by its input: This makes it much easier to document its behavior, and strengthens the explanatory power of type signatures.
- Such functions are much easier to test than OO methods that change state, and that might need “setup” and “teardown”.
- Implicit dependencies through global state are greatly reduced, which leads to a reduction in coupling of an order of magnitude.
- Functions in the software correspond to mathematical functions and thus enable the use of mathematical reasoning – more about that later.
- In concurrent programs, it is not necessary to perform expensive and hard-to-get-right synchronization to access shared state.
If you find this unintuitive, you might be pleasantly surprised how easy this is in practice, and how close it is to the way human perception works – make snapshots instead of using setter methods to destroy the past.
(OO experts might argue that it’s a well-known and good OO practice to use “value objects” – i. e. immutable ones. Indeed!)
Powerful abstractions means that functional programming enables abstractions at a higher level than OO does. Some of those universal abstractions already made their way to OO languages, like the
map method on collections. Those, however, are only the tip of an iceberg of libraries with abstract useful ideas. OO languages have acquired many functional features (“lambda”), but their usage is still often clunky and cumbersome compared to real FP languages – and that makes those FP abstractions less useful there.
Abstraction is generally something that happens more often in functional architecture than in OO, even and especially when it comes to concrete domains. Functional languages are more uniform than their OO counterparts, and this makes abstraction in functional architecture more systematic. As a result, it goes wrong only rarely.
This “systematic abstraction” is additionally supported through the availability of mathematical concepts, specifically from algebra.
Many domain models exhibit properties that algebra has catalogued and investigated for hundreds of years. (Some people shun the use of mathematics in software development. That’s really a shame, as math was the method of choice for formally modelling the world around us before there were computers. It has yielded invaluable experience and insights.) Indeed, mathematical concepts such as “monoid” or “functor” often yield fresh domain insights.
Moreover, the transition from such models to veritable domain-specific languages is fluid.
Another important difference: Functional architecture is code, and constructing it does not require using an intermediate notation. This is also enabled by the improved expressiveness of functional languages, which makes the “bird’s-eye view” of the architecture directly apparent.
Functional architecture really is a different world, and it’s quite daunting for a three-day training. Consequently, you should bring (in addition to some curiosity) some basic knowledge of functional programming. But don’t worry, open FUNAR trainings usually come with a one-day “pre-training” that will provide that knowledge. If you’re open for the challenge, you’ll come back with many insights, some which are also directly applicable in an object-oriented setting. A good example is domain modelling using combinators. The training also provides a bridge to Domain-Driven Design, which works even better with FP than with OO.
Completing the training gets you 10 credit points for competence in methodology and 20 credit points for competence in technology. We’re looking forward to seeing you at FUNAR!