Functional programming discourages the mutable state, and qualifies data structures as everlasting values. Variable may be assigned a new value (a new data structure derived from old by pure functions), but the existing data structures should be never mutated. The paradigm has shifted from procedural state machine to modelling the functionality as long chain of pure functions wired together. Thus coupling in the system is reduced and theoretically it should be easier to reason about and track the bugs.
But the business domain of problems we are trying to solve in web development are naturally object oriented. We are talking about entities and their attributes. An identity and it's state. The state is stored in the database. When we are making money transaction, we are mutating the specific bank account to withdraw/save the money. We are not thinking about replacing the bank account with new one for each transaction. They are mutable objects per se. This state has to be mutated somehow, somewhere. I realize functional languages doesn't deny the state (it's inevitable after all) but favors side effect free syntax which makes the mutating operations feel awkward.
Now, what is the approach of functional languages to target the very object oriented nature of the real world? For example clojure doesn't have the concept of class, thus I guess it doesn't have ORM. How would it align to the relational world of enterprise business? Would the paradigm even know the concept called entity? Would it be allowed to mutate such an entity? Or would the functional programming need a shift in style how we store the data too?
This whole functional approach seems so theoretical and contradictory to the real world. How would I gain more insight how all this works in the real world scenarios of web development?
It's probably worth while to start from Stuart Halloway's presentation on Clojure's Time Model.
Making no promises to do the talk justice: entities have state. Note that's has-A, not is-A; so we should be thinking about composition. Conceptually, what we think of as an object is a mutable reference to immutable state.
Now, if you look at this through the lens of Bertrand Meyer's CQS; query support is easy - queries don't modify the state of the object, so they are in effect a pure function
result = query(this.currentState)
Command support, on the other hand, can trivially be broken into two parts, a query that produces a new state, and a change to the mutable reference.
State nextState = query(this.currentState)
{ref-set} this.currentState = nextState
As Lee noted in his comment, currentState and history are dual to one another, which is to say, we can just as easily turn the above example around
// conceptually, this is still a _query_; we aren't mutating current state
// but are instead calculating a new value.
State nextState = this.currentState.apply(command)
{ref-set} this.currentState = nextState
In eventsourcing, we're a bit more careful about the distinction between the output of the command of the current model, and the history of the changes, so the spelling tends to look more like
// conceptually, this is still a _query_; we aren't mutating current state
// but are instead calculating a new value.
Events changes = command(this.currentState)
State nextState = this.currentState.apply(changes)
{ref-set} this.currentState = nextState
Taken across the entire history of the entity, you get
State state = fold(history, State.SEED)
{ref-set} this.currentState = state
The state is stored in the database.
Almost: state is stored in the database.
State nextState = database.currentState.apply(command)
{ref-set} database.currentState = nextState
For instance, Greg Young describes Event Store as having only 32 bytes of mutable state. Everything else is write once.
This whole functional approach seems so theoretical and contradictory to the real world.
Not at all -- remember, the past is immutable; models that allow you to change the past don't align with the constraints of the real world.
How would I gain more insight how all this works in the real world scenarios of web development?
For starters, look up Greg Young's talks on event sourcing (especially his newer ones; he's been getting more functional over time), and also Mark Seemann's blog. In addition to everything you can find by Stuart or Rich Hickey.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With