Live data from Hacker News

Destroy All Ifs – A Perspective from Functional Programming

degoes.net

121–130 of 226 posts

Re: Destroy All Ifs – A Perspective from Functional Programming

#121
post #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…

> 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. This is trivially true, any datatype can be encoded as a function. The post is not saying that we can pass any type of lambda whatsoever, but that we should pass lambdas that implement the required functionality. > The straw man…

> This is trivially true, any datatype can be encoded as a function.

To elaborate: this is called the church encoding of the data type. Particularly interesting for recursive data types.

The most common example is probably 'foldr' (or 'reduce' in Lisp-parlance) for linked lists.

Re: Destroy All Ifs – A Perspective from Functional Programming

#122

Earlier quoted context omitted.

since I'm not a fp expert what about a function like ctx.arc(10, 20, 30, 0, 6.28, false); There's nothing special about boolean. How do you encode all of those above into types in fp so that it's impossible to get them wrong and so they're self documenting? I hope you're not suggesting there be a horizontalFloat type and a verticalFloat type or are you?

I'm a big fan of the philosophy that "Every literal in a program is a bug." :) But I know what you're getting at! Personally, I'm a fan of programming with units and dimensions, and safely representing the distinction between absolute quantities and relative quantities. That doesn't mean I'd want an infinite number of "float" values for all possible units and dimensions, however; just a powerful enough type system I…

> "Every literal in a program is a bug."

But we use plenty of literals in our programs all the time. Eg lambdas are function literals. (And definitions of named functions are just a special case folding binding and a lambda.)

Re: Destroy All Ifs – A Perspective from Functional Programming

#123
post #82

I'm surprised that the article and none of the comments so far mentioned the "Expression Problem": http://c2.com/cgi/wiki?ExpressionProblem Basically, if you structure the control flow in object oriented style (or church encoding...) then its easy to extend your program with new "classes" but if you want to add a new methods then you must go back and rewrite all your classes. On the other hand, if you use if-statemen…

FP and particularly the Haskell community is very aware of the expression problem and you can find many blog posts and papers on solutions.

That 'ufo' knows about the name expression problem at all betrays that they are very aware of that work in the FP community.

Re: Destroy All Ifs – A Perspective from Functional Programming

#124

Earlier quoted context omitted.

There are languages (libraries) that solve it. For reference, check Clojure's multimethods and OCaml's polymorphic variants.

The tradeoff is that techniques like multimethods significantly weaken the contract that people normally expect from methods/classes. For example, if I'm writing a normal Java class, I know where I go to find methods dealing specifically with instances Foo (namely Foo and its children and direct users); with multimethods, it's more likely that there is some multimethod out there in an unrelated class that looks for i…

Good tooling (think something along the lines of Hoogle) can help here.

Re: Destroy All Ifs – A Perspective from Functional Programming

#125
post #82

I'm surprised that the article and none of the comments so far mentioned the "Expression Problem": http://c2.com/cgi/wiki?ExpressionProblem Basically, if you structure the control flow in object oriented style (or church encoding...) then its easy to extend your program with new "classes" but if you want to add a new methods then you must go back and rewrite all your classes. On the other hand, if you use if-statemen…

I was familiar with the problem but didn't have a name for it; thanks for providing me with one. What kind of work has there been on creating programming paradigms that make it easy to both add new types and new methods? Is it a CAP-theorem-type problem where every solution is a trade-off, or is there a way to have your cake and eat it too?

here was an interesting proposal for a solution in C++ https://channel9.msdn.com/Events/CPP/C-PP-Con-2014/0007-Acce...

Re: Destroy All Ifs – A Perspective from Functional Programming

#126

Earlier quoted context omitted.

since I'm not a fp expert what about a function like ctx.arc(10, 20, 30, 0, 6.28, false); There's nothing special about boolean. How do you encode all of those above into types in fp so that it's impossible to get them wrong and so they're self documenting? I hope you're not suggesting there be a horizontalFloat type and a verticalFloat type or are you?

How about keyword parameters... ctx.arc(center=Point(10,20), radius=30, beginAngle=0, endAngle=6.28, Clockwise); ...and don't forget about units of measurement/dimensional analysis. https://stackoverflow.com/questions/107243/are-units-of-meas... ctx.arc(center=Point(10cm,20cm), radius=30mm, beginAngle=0rad, endAngle=6.28rad, Clockwise);

Assuming you're right about the guesses for those parameters, we could go a little further. Let's define

   data Directionality = Clockwise | Anticlockwise

   data AngularInterval = {
     beginAngle :: Double,
     endAngle :: Double,
     directionality :: Directionality
   }
... and then we're down to three parameters, all of different types (so no opportunity for mistakes, assuming static checking) and who knows, you might even have other uses for AngularInterval.

Re: Destroy All Ifs – A Perspective from Functional Programming

#127

Problem is, a decision has to be made somewhere about which function to pass into that "if-free" block of code. The if-like decision has just moved elsewhere. That is a win if it reduces duplication: if a lambda can be decided upon and then used in several places, that's better than making the same Boolean decision in those several places. Programs that are full of function indirection aren't necessarily easier to un…

In a language like Haskell you wouldn't want to prove the absence of recursion, but that all recursions in the program fit into a handful of patterns. (Eg 'structural-recursion' or 'tail-recursion'.)

Some type systems are strong enough to put that kind of analysis / constraints directly into the language. (Haskell might already be strong enough with GADTs and other language extensions enabled.)

In any case, the Addendum at the end of the blog post provide a different perspective on the problem you mentioned.

Re: Destroy All Ifs – A Perspective from Functional Programming

#128
post #117

Earlier quoted context omitted.

Someone else addressed the details of your counter argument, but I'd like to respond to it generally. It seems like every time someone writes an article on how to write better code, there are responses about how it doesn't make sense when taken to some logical extreme, or some special case, as if that invalidates the argument. (FP techniques in particular seem to provoke this.) But code design is like other design di…

The title says "destroy all ifs". The author already did take the idea to the extreme himself.

It's true. Personally, I took that to be a bit tongue in cheek. I would compare it to "GOTO Considered Harmful"-- where the author wants you to imagine a world without such a technique in order to expand your abilities. (Even though there are probably edge cases where such usage is justifiable.)

Re: Destroy All Ifs – A Perspective from Functional Programming

#129

This is, as many commenters have noted, just another overzealous programming doctrine. Just like 'GOTO considered harmful.' Here's the deal: if is a flow control primitive. Just like goto and while. If (heh) that primitive isn't high-level enough to handle the problem you are facing, it is incumbent upon you as a programmer to use another, higher level construct. That construct may be pattern matching, it may be poly…

Not all control-flow primitives are necessary.

Eg Haskell and Scheme get by without 'while' and 'goto'.

Haskell would do just fine without a built-in 'if': you can define 'if' as a function via pattern matching.

Given that perspective, the article would be a call to use more expressive types than Booleans to match on---and in lots of cases not to match at all, but provide what would be the result of the match as an argument to the function.

Re: Destroy All Ifs – A Perspective from Functional Programming

#130

Earlier quoted context omitted.

I think that aiming at the management of the coders and the business users is putting the emphasis in exactly the right place. Once we get to womdering if eliminating IF stmts will help, we have passed by so many opportunities for 10x value delivery.

The "technical debt" metaphor gets so much better if you take the analogy more literally than most people do. Like for financial debt, the optimal amount is not necessarily zero. Oftentimes taking on or carrying debt allows you to generate more profit than you could by avoiding it or paying it down. That said, most places I've worked manage it poorly. Few people really understand that, just like financial debt, it's…

Also, if you do take the finance metaphor, going into debt is not good by itself. It's the investments you make with that debt that are good, and potentially outweigh the burden of debt. (And can be cheaper than equity financing.)

Going back to programming: debt-fuelled programming should buy you something, eg speed to market, and is not a good in itself.

Post reply on HN