Hacker News new | past | comments | ask | show | jobs | submit login

Articles like this really make me think... that maybe the Haskell and FP people have their heads in the clouds.

I've played with OCaml, Haskell, Erlang, Scheme and Common Lisp, and I always end up going back to Python, C, and C++ for all of my "real" development.

IMO the abstractions available in the more mainstream languages are easier to understand and use in almost every case. They also perform better on existing hardware.

This particular article is really bad because most of its arguments are straw men.

For example:

"Instead, higher level operations like sum, prod and concat are defined in terms of folds. And your code is then written in terms of these higher-level reducing operations, making your code more concise, easier to read, easier to write, and easier to understand."

Building higher level abstractions from the language's lower level abstractions is basically the entire point of programming in any language. It's convenient that Haskell's library includes functions like sum, prod and concat, but it's hardly the only language including them, and it's trivial to write them correctly and reuse them in the languages without them.

And then he says stuff like "If you're still not worried about bugs, think about the possible typos. Then think about how often you write loops like this." Because nobody ever makes typos while using folds and closures, right?




The bog-standard for loop that transforms an array mentions the array twice and the index variable five times, giving you, let's say, 6 unnecessary chances to goof something:

for (int i = 0; i < array.length; i++) { newarray[i] = f(array[i]) }

by contrast, the functional-programming method allows you to define the new array immediately in terms of the old one, just mentioning the latter once and without an index variable:

  newlist = map f oldlist
To my eye, this gives me far fewer chances to botch it, and my reader can instantly tell that

  (1) newlist corresponds to oldlist in length and order
  (2) the only difference between the two is that the elements are related by the function f.
Every time I come across a for loop that builds up an array, I worry whether the bounds checking is wrong, whether the right index variable is used (esp. if there are nested loops), and whether an elements were added to the array before or after the loop. Lots to worry about.


Or you can worry about performance. Or memory usage. Or blowing the stack. Or...

There's no free lunch.


You still have to worry about performance and memory usage with a for loop. You don't have to worry about blowing the stack, but you wouldn't have to worry about that in a language with proper tail call support either.

Admittedly, you do have to worry about the stack in Haskell, but that is entirely the fault of laziness and not recursion or higher-order functions. You're not really worried about a call stack, you're worried about having a really big thunk (deferred expression).

There may be no free lunch, but some are much better value for money than others.


> Because nobody ever makes typos while using folds and closures, right?

If you type flod instead of fold, the compiler will complain. If you have an off-by-one error in your for loop, not so much.


If you type foldr instead of foldl it won't complain.


In most cases it will because they have different types:

    foldl :: (a -> b -> a) -> a -> [b] -> a
    foldr :: (a -> b -> b) -> b -> [a] -> b
So the only time it will be the same is if a and b are the same type.


> So the only time it will be the same is if a and b are the same type.

Which they will be in most of the example code he used. They're not the best examples.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: