https://medium.com/clean-code-development/stratified-design-...
It's a cryptographic identity protocol. It's architected such that the identity is not a document, but rather a DAG of transactions that build the document (more here: https://stamp-protocol.github.io/).
This core library uses the "functional" api aspect I'm talking about. It lets you create and run DAG transactions, but doesn't save them or generate keys for you or anything like that. When you create a transaction, you have to pass in all the data required to complete it, and when it completes, it returns back a full transaction set (or an error).
There are some utility functions in there that are not entirely functional, but the gist of it is that 95% of the things you do have no side effects and have to be dealt with outside of the library itself.
As far as a REST API, you're dealing with a large number of inputs/outputs (side effects) so this paradigm might be limited. However, you can still think in terms of side effects (HTTP request, HTTP response, database, third-party HTTP calls) and compartmentalize your logic from those operations into functional units: if I `POST /users?name=andrew&likes=[dogs,programming]` then instead of going
routes/user::save()
-> models/user::save(params)
-> models/db::run_query(qry, params)
you might do something like routes/user::save()
-> models/user::create_user_instance(params)
-> models/user::create_user_query(user{andrew, [dogs, programming])
-> models/db::run_query(qry, params)
Here, you flatten out your call stack, functionalize your calls (create_user_instance and create_user_query will ALWAYS return the same values given the same params) and move your final database call up the stack (as high as you can afford to). Obviously calling the DB in a route is dumb, but hopefully you get the general idea.I also usually find currying extremely practical and easier for me when it's available.
Most of us that only use FP in our day job don't do it out of masochism, AFAICT. I certainly don't.
And I don't think recursion is a GOTO that should be avoided. It's a useful tool that's easy to read and reason about.
Yes recursion is a useful tool, just like GOTO and is sometimes necessary or more practical. But it is better to e.g. use a fold if you can because that further constrains and aids reasoning. For example, a fold will always terminate unlike general recursion.
I recommend looking into recursion schemes, if you aren't familiar with them.
https://github.com/willtim/recursion-schemes/blob/master/sli...
I know this seems obvious, but it was a breakthrough I had with organizing the way I built things a few years back and it has been serving me amazingly well. I think I originally stumbled onto the idea through a talk on domain-driven development.
The result is that you get a lot of the benefits of functional (easy testing, portability, etc) but you don't have to deal with all the oddball patterns of recursion or currying or things that, yeah, sure, makes sense on some theoretical level but makes me want to gouge my eyes out when I try to read it. I've tried fully-fledged functional programming in a few cases and it doesn't click with me. I appreciate and understand that some love it, but in the end if your exposed public API is functional, the internals are less important.
To me the important thing is the mindset: move your side effects as high up the chain as you can.