Can anyone offer the skeptical perspective? Are Free monads all the author claims they are? One concern I have is, with only reading his posts, is it seems like adding a new operation to the language involves change multiple places.
I’m mostly a believer, and coming at this from a Scala perspective, but I can offer a bit of skepticism. Free monads really are all the author claims they are, and adding a new operation to the language shouldn’t impact other places at all (particularly with the various coproduct styles) - only the use site and the interpretation site.
Performance isn’t yet sorted - the datastructures involved theoretically have nice big-O behaviour, but the constant factors kill you at the moment. Well, I say kill - it’s more like they bring performance down to a Python/Ruby-type level, which is still adequate for many cases. Compile-time performance can also be an issue, though I think that’s more a matter of compilers not being designed for these use styles than anything fundamental. Ultimately if the compiler ended up implementing specific optimizations for this style it wouldn’t be much of a problem IMO - the fact that the style can be implemented as a library proves that it is well-founded, an optimization would just be an optimization.
The article points out that monads are impossible to actually write optimizing interpreters for and then proceeds to more-or-less ignore that. Applicatives would be a solution, but no-one actually has a free applicative library and applicatives probably aren’t powerful enough to implement the behaviour you want. Fetch (the scala library) has something that pretends to be a free applicative and also a free monad, with the result that it violates several important identities and it’s impossible to reason about performance when refactoring. I suspect what we actually need is free ArrowChoices, but I haven’t heard anyone even start to talk/think about those.
And most programs belong to a single domain - they wouldn’t really make sense otherwise. So you don’t really need generic concepts of interpreters, languages and so on - you can get all the benefits of the “onion architecture” by building a particular, concrete tree of languages and interpreters. It’s hard to even imagine the kind of program that would actually need to do generic higher-order composition of interpreters, elegant as it may be. In theory a library at higher level might make it easier to write program-specific interpreter hierarchies, but I’m not sure where the overhead to be eliminated is - as far as I can tell writing a monad -> monad interpreter is already about as concise as it could ever possibly be while still capturing the actual business-specific logic that you need.
On the one hand, I assumed data structure traversal was already as concise as it could possibly be before finding recursion-schemes. On the other hand, the actual code saving I’ve seen from recursion-schemes style approaches is pretty minimal. So maybe free coproduct style will make programs clearer and simpler, but I don’t think it’ll make them a whole lot clearer and simpler.
Given your other comments on here I would have thought you’d be all for this so your critical response is informative and welcomed, thank you.
I think it’s the future (heck, I’m writing a library for it), and certainly a worthy research area, but I don’t think it’s production-ready yet - certainly not for performance-critical domains.
When I realized that this was the guy who was peddling free monad interpreters last year, I thought, “great, this guy again”.
mtl-style sans the mtl library itself is seriously underrated.
Did you mean “Great, this guy again” or “Great, this guy again”?
I know the man and I like him very much, but I think even John would admit half of his blog posts are shitposting. They also have a habit of distracting newbies that have more fundamental things to learn. Lots of silly FOMO.