Hacker News new | ask | show | jobs
by qwertyuiop924 3629 days ago
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 polymorphism (or any other form of type-based dynamic dispatch). It may be a function that wraps a complex chain of repeated logic, and is handed lambdas to execute based upon the result. It may, as in the article given here, be a funtion that is handed lambdas which apply or do not apply the transformation described.

The point is, there are many branch constructs, or features that can be used as branch constructs, in most modern programming languages. Use the one that fits your situation. And if that situation isn't a that complex, that construct may be if.

Fizzbuzz using guards is the most clean and modifiable fizzbuzz that I've seen in Haskell.

Although now that I think about it, if you provide a function with a list of numbers...

1 comments

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.

Scheme and Haskell have other primitives that take the place of while and goto.

But yes, using more expressive match types or parameters is a good idea. As for providing the result as an argument, that can be a good pattern, but isn't always practical. Note what I said in my original comment about using your own discretion.

They don't have `other primitives': they have function calls. Most languages have function calls these days.
Yes, I read LTUI and LTUD. But in most languages, function calls and loops don't have the same semantics. I'll call that a different loop primitive.
For C, this seems to be implementation defined.

(At least for C as encountered in the wild, I don't know about C the standard.)

Most modern C compilers support tail call optimization.

I don't know about `most languages'. Eg I know Java on the JVM doesn't do tail call optimization. Lots of languages probably do not require TCO of their implementations, though.