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.
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.
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.
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
mtllibrary 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.