Live data from Hacker News

Destroy All Ifs – A Perspective from Functional Programming

degoes.net

1–10 of 226 posts

Re: Destroy All Ifs – A Perspective from Functional Programming

#3
This just seems to obscure the logic. Not unlike how polymorphism can make code flow harder to read, though feel more clever.

There is a place for it - like when you're trying to express a set of logic that will be guarded by the same condition, but always at the cost of some complexity.

A set of conditionals is probably the most obvious way to express branching.

Re: Destroy All Ifs – A Perspective from Functional Programming

#4

This just seems to obscure the logic. Not unlike how polymorphism can make code flow harder to read, though feel more clever. There is a place for it - like when you're trying to express a set of logic that will be guarded by the same condition, but always at the cost of some complexity. A set of conditionals is probably the most obvious way to express branching.

Try it before you knock it. I might have said something similar before getting into Haskell, but now I'm nodding along happily. Dealing in meaningful data types with small composable functions is very pleasant for me now.

Re: Destroy All Ifs – A Perspective from Functional Programming

#5
Define true as a lambda taking two lazy values that returns the first, and false as one that returns the second, and you can turn all booleans into lambdas with no increase in code clarity.

The straw man in the post - talking about a case-sensitive matcher that selectively called one of two different functions based on a boolean - is indeed trivially converted into calling a single function passed as an argument, but it's hard to say that it's an improvement. Now the knowledge of how the comparison is done is inlined at every call point, and if you want to change the mechanism of comparison (perhaps introduce locale sensitive comparison), you need to change a lot more code.

That's one of the downsides of over-abstraction and over-generalization: instead of a tool, a library gives you a box of kit components and you have to assemble the tool yourself. Sure, it might be more flexible, but sometimes you want just the tool, without needing to understand how it's put together. And a good tool for a single purpose is usually surprisingly better than a multi-tool gizmo. If you have a lot of need for different tools that have similar substructure, then compromises make more sense.

This is just another case of the tradeoff between abstraction and concreteness, and as usual, context, taste and the experience of the maintainers (i.e. go with what other people are most likely to be familiar with) matters more than any absolute dictum.

Re: Destroy All Ifs – A Perspective from Functional Programming

#6
The idea that each type has its own control flow primitives is bothersome. It's taken over Rust:

    argv.nth(1)
        .ok_or("Please give at least one argument".to_owned())
        .and_then(|arg| arg.parse::().map_err(|err| err.to_string()))
        .map(|n| 2 * n)
I'm waiting for

    date.if_weekday(|arg| ...)
Reading this kind of thing is hard. All those subexpressions are nameless, and usually comment-less. This isn't pure functional programming, either; those expressions can have side effects.

Re: Destroy All Ifs – A Perspective from Functional Programming

#7
post #6

The idea that each type has its own control flow primitives is bothersome. It's taken over Rust: argv.nth(1) .ok_or("Please give at least one argument".to_owned()) .and_then(|arg| arg.parse:: ().map_err(|err| err.to_string())) .map(|n| 2 * n) I'm waiting for date.if_weekday(|arg| ...) Reading this kind of thing is hard. All those subexpressions are nameless, and usually comment-less. This isn't pure functional progra…

Most of this should be obviated when the ? operator is ready. But until then, there is no primitive for 'work on the type you wrapped in Option, short-circuiting and returning None at the first sign of failure', so it has to be done in the library.
Post reply on HN