
Haskell: It’s like Klingon, but with math - iamelgringo
http://www.sdtimes.com/content/article.aspx?ArticleID=33399
======
Periodic
I can definitely say that Klingon isn't a language you can just jump into.
Er... I mean Haskell.

However, being the first functional language I'm really starting to grok I'm
amazed at how powerful and concise it is.

Wasn't it Eric S. Raymond that told us we should all learn at least one
functional language (namely lisp) in our lives not necessarily to program in,
but to make us a better programmers?

~~~
yummyfajitas
Not just concise, but also readable. An example: translate lists into 'english
text' lists. That is ["Apples"] -> "Apples", ["Apples", "Oranges"] -> "Apples
and Oranges", ["Apples", "Oranges", "Pears"] -> "Apples, Oranges and Pears",
etc.

(Problem a slight modification of the one described here:
[http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-q...](http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-
quibbling.aspx) )

The haskell solution:

    
    
        englishList [] = ""
        englishList [only] = only
        englishList [first,last] = first ++ " and " ++ last
        englishList (first:rest) = first ++ ", " ++ (englishList rest)
    

It's short, but completely readable. Compare that to the solutions given in
the blog comments.

~~~
ezy
Ok, I'll be the nudge and say I don't understand the point. I never "got" this
type of example from the lispers using destructuring and recursion on simple
examples either.

This (and others) has a fairly obvious and equally readable counterpart in C++
(or any other imperative language, really), but there's a reason why one
doesn't implement it this way in those languages -- and a reason why (some of)
the examples given have a certain bias towards iteration.

Wouldn't the same reason hold in haskell? Or do we care about runtime
efficiency at all?

~~~
derefr
The Haskell example compiles to an iterative version, as far as I'm aware.

~~~
jganetsk
It complies to neither an iterative NOR a recursive version. It compiles to
LAZY version. This code doesn't loop at all. It forces the argument just deep
enough to go three nodes into the list spine. Then, picks the branch based on
the number items in the list, forces the first element of the list, and sets
up a thunk for appending everything on later.

This was a little bit of a simplification of things; I don't need to go into
great detail to make my point.

~~~
derefr
Okay, but in doing so, it's not pushing an extra stack frame with each step,
but rather just jmping its way along, correct? That's what most people think
of as being iterative (or tail-recursive), rather than simply recursive,
behaviour, and it can apply equally to a lazy algorithm.

~~~
jganetsk
No, you can't simply apply that analysis to lazy algorithms. foldr is not a
tail-recursive function in a strict language. However, in a lazy language,
foldr may not push O(n) frames on the stack.

The code you are looking at here is NOT tail-recursive. Haskell's
implementation of ++, in a strict language, will always push O(n) frames on
the stack.

But it IS true that this code is O(1) in stack consumption with Haskell's
execution model.

------
fiaz
I know this comment is totally off-topic, but that headline is absolutely
killer!

Good article too!

~~~
alexitosrv
Is one of the best titles I read today!

