I’m not convinced. I read the article thinking that if I had to debug something like this, I’d just end up rewriting the whole thing as a for loop.
This is especially true if I’m not working with the code often. I’d have to actually look up every single one of those functions to be sure they do what I expect and then piece everything together in my head before trying to make my change that doesn’t break everyone’s expectations (assuming I found the bug easily.. can’t imagine using a debugger).
My heart goes out to everyone using python and JavaScript. The exceptions for error handling and lack of types makes everything needlessly difficult to do (and esp maintain), but I really don’t believe this is the solution.
I find it weird to focus so much on the syntactic level here. Yes, pipe operators in functional languages are nice, but they exist mostly to work around the fact that humans think left to right and lambda calculus is evaluates right to left. Typical OO syntax operates left to right and so, completely ignoring the semantics of the language, is a better fit for humans. Starting with a language that expresses evaluation left to right, rewriting your code to evaluate right to left and hen adding another layer to get back where you started is baroque.
That’s not to say that FP does not have advantages. Immutability and side-effect-free computation are fantastic tools for local reasoning, whereas imperative languages with global state and arbitrary side effects can lead to all sorts of spooky-action-at-a-distance debugging problems. The cost of this is that writing the code in a functional style is more constraining. That’s often a good trade off, because making code a bit harder to write in exchange for making it a lot easier to debug is generally a net win.
Unfortunately, when you write in a functional style in a language like JavaScript, you end up imposing these constraints on yourself but not getting any of the guarantees that provide the benefits. Any method that you call (including implicitly via field access) may mutate the objects that your operating over and may even have side effects elsewhere in your program or outside. If you want these benefits in JavaScript then you’re better off spawning a web worker, which has no access to the rest of your program’s state and so enforces isolation for a phase of computation.
It actually is. If you read human-interface guidelines from the ‘90s, they argue as you do and tell you to invert button order in right-to-left-reading-order languages. More recent research (from about 10-20 years ago) tells us that this was not sensible: people’s perception that left is back and right is forward is unrelated to their native reading language. This is why modern HIGs recommend to use <- for back and -> for forward in all locales (and, I believe, all web browsers do).
“We should have hyped function composition and referential transparency, not .map() and passing the world into functions…” as the fires rage on the horizon, cracked ground along arid planes of the northern hemisphere wearing our callused feet thin
This is the second article I’ve seen that’s a sample from this upcoming book. The code in this article suffers from the same issues in this great comment. I think the messaging/marketing of functional programming really missed the mark if people consider “folds in order” meaningfully functional code just because no data gets mutated. @Casperin’s answer is completely fair. let result = notification.forEach(notification => nested(functions(or(whatever(notification))))) // lol
Code like this is great for teaching/learning new concepts and ways to think about problems. That being said, I’d never let anything like this past code review.
I’m not convinced. I read the article thinking that if I had to debug something like this, I’d just end up rewriting the whole thing as a for loop.
This is especially true if I’m not working with the code often. I’d have to actually look up every single one of those functions to be sure they do what I expect and then piece everything together in my head before trying to make my change that doesn’t break everyone’s expectations (assuming I found the bug easily.. can’t imagine using a debugger).
My heart goes out to everyone using python and JavaScript. The exceptions for error handling and lack of types makes everything needlessly difficult to do (and esp maintain), but I really don’t believe this is the solution.
I find it weird to focus so much on the syntactic level here. Yes, pipe operators in functional languages are nice, but they exist mostly to work around the fact that humans think left to right and lambda calculus is evaluates right to left. Typical OO syntax operates left to right and so, completely ignoring the semantics of the language, is a better fit for humans. Starting with a language that expresses evaluation left to right, rewriting your code to evaluate right to left and hen adding another layer to get back where you started is baroque.
That’s not to say that FP does not have advantages. Immutability and side-effect-free computation are fantastic tools for local reasoning, whereas imperative languages with global state and arbitrary side effects can lead to all sorts of spooky-action-at-a-distance debugging problems. The cost of this is that writing the code in a functional style is more constraining. That’s often a good trade off, because making code a bit harder to write in exchange for making it a lot easier to debug is generally a net win.
Unfortunately, when you write in a functional style in a language like JavaScript, you end up imposing these constraints on yourself but not getting any of the guarantees that provide the benefits. Any method that you call (including implicitly via field access) may mutate the objects that your operating over and may even have side effects elsewhere in your program or outside. If you want these benefits in JavaScript then you’re better off spawning a web worker, which has no access to the rest of your program’s state and so enforces isolation for a phase of computation.
This isn’t true, lots of languages are right to left.
It actually is. If you read human-interface guidelines from the ‘90s, they argue as you do and tell you to invert button order in right-to-left-reading-order languages. More recent research (from about 10-20 years ago) tells us that this was not sensible: people’s perception that left is back and right is forward is unrelated to their native reading language. This is why modern HIGs recommend to use <- for back and -> for forward in all locales (and, I believe, all web browsers do).
That is fascinating. Can you point me at any off this research?
Articles like this leave me convinced that 10 years from now we’ll be kinda embarrassed at how much we hyped FP.
“We should have hyped function composition and referential transparency, not .map() and passing the world into functions…” as the fires rage on the horizon, cracked ground along arid planes of the northern hemisphere wearing our callused feet thin
This is the second article I’ve seen that’s a sample from this upcoming book. The code in this article suffers from the same issues in this great comment. I think the messaging/marketing of functional programming really missed the mark if people consider “folds in order” meaningfully functional code just because no data gets mutated. @Casperin’s answer is completely fair.
let result = notification.forEach(notification => nested(functions(or(whatever(notification))))) // lol
Code like this is great for teaching/learning new concepts and ways to think about problems. That being said, I’d never let anything like this past code review.
The typewriter font is not very readable. Especially the capital K.
Looks like Gabriele Ribbon FG. And I agree, it’s a poor typeface choice for a post with so much code in it.