4 ms·
> That said, I still think passing the world in and out of every function is too onerous for most real world programs [...] This is a bit of a strawman. At lea
by Twisol 6y ago
> That said, I still think passing the world in and out of every function is too onerous for most real world programs [...]
This is a bit of a strawman. At least in my limited experience, functional programmers think so too. Part of what monads let you do is a kind of inversion of control: instead of changing the world directly (as you would if you were seriously threading the world through your domain logic), you return a description of what you're doing, and let the runtime (in the case of IO) or the interpreter for the monad (in other cases) actually perform the changes.
Similarly, lenses allow you to describe local mutations and lift them to the level of a whole structure.
Explicitly threading your state is the first refactoring, not the final destination. If you have a code smell, the first thing to do is draw it out into the open so you can wrangle it. In languages that don't conveniently support functional strategies like monads or lenses, it's tempting to stop there. But that doesn't mean FP is about stopping there.
- voodootrucker 6y agoThanks, your comment caused me to learn what a lense is.
- IshKebab 6y agoYou still have to pass your logging code to every function that does logging right? And if you add logging to a function deep in your call stack you have to go all the way up the stack adding it as a parameter everywhere. It's rigorously correct, but I feel like it's a step too far for most programs.
- Twisol 6y ago> You still have to pass your logging code to every function that does logging right? Yes, but no. Again, there are functional patterns you can apply. First, functional programs tend to be more horizontally composed than vertically. Side effects usually happen at the same "level" of the application, rather than occuring at multiple depths. So the need to thread logging apparati is already reduced, simply because logging only happens higher up in the application. Second, because side-effects only really occur at this thin layer, you can capture logging as a monadic action, avoiding the need to explicitly thread the logger state around. (This is the same situation as the "thread the world" problem we discussed earlier.) Third, because so much more of your program is pure, it is much easier to perform unit tests and check assertions in other ways. At that level, logging is a bandaid over poor testing and assurance, not a goal in itself. Finally, if you do find yourself deep down-stack with a need to perform some kind of side-effect, you can apply logical methods (a la LVars, CRDTs) to give a stateful interaction between separated parts of your program. The Haxl paper [0] is a good example of this: most of the design is pure functional, but for the part that involve an interaction not easily captured by the fundamental call-return / request-response pattern, they utilize monotonic state to maintain a registry of fulfilled and unfulfilled requests. [0] https://simonmar.github.io/bib/papers/haxl-icfp14.pdf https://simonmar.github.io/bib/papers/haxl-icfp14.pdf > It's rigorously correct, but I feel like it's a step too far for most programs. I feel you're being too dismissive. There is an entire community of developers -- many of whom operate in industry -- who can and do effectively solve the problems you are raising. "Rigorously correct" is one of those things non-FP folks think FP is about. You can write buggy code in any paradigm. What people like about FP is that it's easier to reason about, and it's generally easier to find precise abstractions that support that kind of reasoning. "Rigorously correct" is missing the point.
- IshKebab 6y ago> because logging only happens higher up in the application. But... what if I don't want it to? You can't have logging higher up in the stack if you want to log stuff low down in the stack.
- Twisol 6y agoI'm having a hard time reading your question as anything other than "But what if I want to not do functional programming?" As stated, functional programs tend to be shallower. There's less "higher" and "lower" to begin with. I've written plenty -- I'm not interested in responding to potshots every time.