Earlier quoted context omitted.
> Try it before you knock it. That's what I recommend too[0] - with the added caveat that you shouldn't be afraid to "knock it" if it turns out to be honestly bad. Sometimes the idea turns out bad, sometimes it turns out great - but you'll never know it if you don't try; just be honest with yourself during that trial. [0] - https://news.ycombinator.com/item?id=12108138
Absolutely, but I'd also add that what works in one language/environment may not work in another. I wouldn't be surprised if writing Haskell-style code in Python didn't work out that well, for example!
Destroy All Ifs – A Perspective from Functional Programming
41–50 of 226 posts
Re: Destroy All Ifs – A Perspective from Functional Programming
#42Often times when I read about "ideal" ways of programming, I'm curious if it's ever implemented in a production code base built by a team.
Re: Destroy All Ifs – A Perspective from Functional Programming
#43Often times when I read about "ideal" ways of programming, I'm curious if it's ever implemented in a production code base built by a team.
The more I write code the more I realize that the entire purpose of the code is to have some effect on reality, and the more reliably it can do this, the better the code. I find I code a lot better without design principles, because trying to remember which patterns are "good" and "bad" just obscures the attention I would have used to look at the code and sense whether something would work in this particular situation.
Re: Destroy All Ifs – A Perspective from Functional Programming
#44Define 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…
Let's take the following function invocation, which can be expressed with Boolean literals or Church encoded booleans, I don't care:
match true false
If you want to determine the significance of the boolean values passed to this function, it does not suffice to go to the definition of 'true' or the definition of 'false'.Now take something like this:
match caseInsensitive contains
Even though I have used descriptive names here, it's almost beside the point; I could just have easily have used nonsense names: match foobar quux
If you want to know what 'foobar' means, you can go to its definition, and see how it preprocesses a string and a pattern. You don't have to guess about the meaning of a bit.As a result, the semantics of 'match' and its parameters are all communicated more clearly, with less room for error, and much more generality.
There need not be any syntactic overhead: it is merely the replacement of some flag with a lambda which cleanly encapsulates the effect that would otherwise be encoded in the flag. The way you invoke the function is the same, but instead of twiddling bits to get what you want, you pass functions whose meaning does not require (as much) subjective and possibly error-prone interpretation.
Note this also objectively simplifies the functions themselves, because they formerly contained conditional logic, but once you rip that out and give them no choice (invert the control!), they have less room to err, which makes them easier to get right, easier to maintain, and easier to test.
There is also another way to view the issue: with booleans, we first encode our intentions into a data structure (at the caller site), and then we decode the data structure into intentions (at the callee site).
Well, why are we packing and unpacking our intentions into data structures? Why not just pass them through?
Indeed, we do that by pulling out the code and propagating it to the caller site (possibly with names so you don't need significantly different syntax and can benefit from reuse). Then our code more directly reflects our intentions, because we're not serializing them into and out of bits.
I think the general principle applies to more than booleans, but it's easiest to see with booleans.
Re: Destroy All Ifs – A Perspective from Functional Programming
#45The author seems to ignore the fact that passing lambdas like this merely changes where the IF or SWITCH statement is made. I can agree that passing functions instead of booleans is better and more general. But pretending that IF/SWITCH are thus avoided, is delusional. For instance, at some point there will be a decision made whether the string matching must be case sensitive or not. If the program can do both at run…
Re: Destroy All Ifs – A Perspective from Functional Programming
#46I recommend Bob Harper's essay on "boolean blindness": https://existentialtype.wordpress.com/2011/03/15/boolean-bli... An excerpt: > The problem is computing the bit in the first place. Having done so, you have blinded yourself by reducing the information you have at hand to a bit, and then trying to recover that information later by remembering the provenance of that bit.
Thats why you use Lua, it lets you have multiple return values. So you can get a boolean back to let you know if the strings were the same, an int to know where they ceased matching and a boolean to let you know if they are case different. It's then up to the programmer to decide how much enlightenment they want. The destroy all IF reminds me of GOTO considered harmful of the 70's. There are other ways to fix the pro…
Re: Destroy All Ifs – A Perspective from Functional Programming
#47I read everything I could find on the Anti-IF site and didn't understand what the mission is exactly. They qualify and mention they want to remove the bad and dangerous IFs, but I couldn't find examples that differentiate between bad ones and good ones -- are there good ones according to this campaign? I like using functional as much as anyone, and removing branching often does make the code clearer and remove the po…
I have a similar problem, in that every time I try to understand the perspective of functional-programming advocates, I find that the authors always seem to illustrate their points with examples like this:
match :: String -> Boolean -> Boolean -> String -> Bool
match pattern ignoreCase globalMatch target = ...
If I'm already literate in Haskell or Clojure or Brainfuck or whatever godawful language that is, then chances are, I'm already familiar with the strengths of the functional approach, and I'm consequently not part of the audience that the author is supposedly trying to reach.So: are there any good pages or articles that argue for for functional programming where the examples can be followed by a traditional C/C++ programmer, or by someone who otherwise hasn't already drunk the functional Kool-Aid?
Re: Destroy All Ifs – A Perspective from Functional Programming
#48Often times when I read about "ideal" ways of programming, I'm curious if it's ever implemented in a production code base built by a team.
I'd love to see what ways of programming tend to be most effective with production teams. My gut thinks the solutions will be a little more boring than our inner magpies will want to admit.
The one the whole team understands and can agree upon.
Re: Destroy All Ifs – A Perspective from Functional Programming
#49Re: Destroy All Ifs – A Perspective from Functional Programming
#50Functional programmers love to emphasize how all the aspects of programming that their pet language is uniquely good at dealing with also happen to be the biggest problems in code maintenance. Is there any actual data on what the biggest problem sources are?