I'm mostly curious about the details behind the flat-file persistence. Is the storage on the same physical machine as the API and Business Logic? If not how is communication done? How do you handle horizontal scalability for either perf or HA reasons?
However, the vision is that eventually we would use Raft or other kinds of consensus on top of the current layer of storage. Event sourcing supposedly should make this kind of replication easy because data is always append-only. Unfortunately the reality of a startup is that we often have to do things quickly and this aspect has been neglected for pretty long.
At least in the Clojure world, STM is not used that much (despite praise) since it's not a good fit for horizontally scalable web servers.
In our architecture (which is of course by no means perfect!) we largely use a single machine for the majority of our interactions so right now we aren’t facing this issue per se.
The real benefit of purity and immutability is managing complexity. People focus way too much on threading, which is a buzzword. As ever, the buzzwordy version of an otherwise good idea is never all it's cracked up to be.
It's all down to context boundaries:
- With a pure function, you can completely understand its behavior by reading just that function's code, and possibly also the code of any other functions it calls.
- With a method that relies on mutable variables, you have to understand not only that method, but also every other method that mutates the variable, and possibly all the code that has a reference to that object.
In the second case, you've potentially got a much wider scope to understand. Almost as wide a scope as you need to understand when global variables are in use. Worse, it's now possible to change that method's behavior without touching any of that method's actual code. It's even possible that you could change it without touching the file that contains it.
In a nutshell, the real benefit of purity and immutability is that it eliminates "spooky action at a distance" type behaviors, and all the intractability that tends to come with them.
Technical considerations aside I'd love to read about the domain-specific advantages that choosing Haskell resulted in, particularly when Capital Match is playing in a quite crowded sector (p2p lending / invoice financing).
I have heard of similar fintechs written in e.g. Ruby that are open to white-labeling their product for other countries. So non-differentiation from cheaper alternatives can be a risk.