Hacker News new | comments | show | ask | jobs | submit login
Haskell is beautiful in practice (monkey.org)
75 points by mariusae on Nov 10, 2009 | hide | past | web | favorite | 16 comments

This article reads like an april fools joke. In one code block, he shows the most complex, incomprehensible haskell code (with special characters sprinkled in all over the place), then the next paragraph he confidently explains how it's so readable and straightforward to understand.

Haskell is cool, but it's one of those languages I'm going to have to accept that I'm not smart enough to program in.

None of those code examples (except the parsec example) are things that you wouldn't be comfortable with after sitting down for an hour with a haskell book.

Parsec is a special case: it's full of unusual operators, because it is really like a DSL for parsing. It is really quite beautifully designed however.

It just annoys me when people look at the language and their brain shuts down because they see a (:) or a ($).

It's not because they're unaccustomed to the special characters in syntax, quite the contrary, it's because those special characters have associated meaning for them, through Perl and Unix shell.

When I was first learning Lisp I was frustrated by the syntax for characters; #\a means the letter a, or 'a' in C, both are three key strokes, and I didn't understand the unusual convention. Well, it's because Lisp allows named characters, like #\Tab and #\Newline, along with custom unicode characters like #\Arabic_Alif. Aha!

Unix-syntax is almost always single-purpose; that doesn't help reuse, and causes reader-table over population. Lisp, and functional-language style syntax is there for a very good reason, usually your own good.

It isn't a language, it's a notation. It's like math. No one tries to read math like an English sentence, so why would you try that with Haskell or even other programming languages?

I think it's time for us to stop calling them "programming languages" and call them something else. I suggest notation, but even "Awkdawdkawd" would be an improvement :|

A hilarious example from the post:

    p_term :: Parser Term
    p_term = t <* spaces    
        t =     IntTerm               <$> p_num (readSigned readDec)
            <|> FloatTerm             <$> p_num (readSigned readFloat)
            <|> AtomTerm              <$> p_atom
            <|> TupleTerm             <$> p_tuple
            <|> BytelistTerm . C.pack <$> p_string
            <|> ListTerm              <$> p_list
            <|> BinaryTerm   . B.pack <$> p_binary
"Again, reading very naturally"

Seems pretty good to me. (I know a little Haskell, but only a little.) I think you and the original author are using different standards of readability. Yours: "If I look at this code, starting without knowing anything about it, does it look familiar?" His: "Once I've taken a few minutes to get the hang of this, is it easy to read and write?".

Here, the <|> and <$> and <* are unfamiliar and weird-looking: fair enough. But once you know that <|> means "or", and <$> means "try to parse some of the input using the thing on the right, and then the thing on the left is the resulting value", and <* means "try to parse both of these, and return the result of parsing the first one", it's hard to see how it could be much simpler.

Even in that code block, <|> and <$> both have roughly the common meanings of | and $ elsewhere in Haskell, which is the "next case" operator for pattern matching expressions and the strictness operator for ensuring that a function is applied to a value correctly.

Only <* is a really new construction.

...and the strictness operator for ensuring that a function is applied to a value correctly.

($) isn't any kind of strictness operator -- maybe you're thinking of ($!). ($) is a plain old function application operator.

It's strictness for applicative precedence, as ($) is the least of the operators, like a greedy open-paren.

I think this is very readable. Out of curiousity, what would your ideal of the equivalent code look like, in your language of choice? (If you really can't read this to know what your code would have to do, it's either parsing some term t or consuming whitespace. In the case where it parses a term, that term is going to be one of IntTerm, FloatTerm, AtomTerm, etc. Each term has its own associated parsing function (specified after the <$>).

I bet somewhere, people are laughing at perfectly nice pieces of python, lisp, or even Java. Just because it's new to them.

What did Gandhi say...

I don't think that block is that bad - it's just a combination of BNF and the normal pattern matching syntax, albeit with <_> operators.

There are examples of Haskell being needlessly hard to read - I'm not a fan of having optional significant whitespace in only some parts of the language, for example - but this isn't a great example.

It's notation, not a natural language stop treating it as such.

code readability is relative.

Well, I liked the article - I have worked through the real world haskell book just enough to sort-of understand this article :-)

That said, I gave up on Haskell. I spend a lot of time semi-learning languages because it is fun. But, for practicality, I really concentrate on knowing just Ruby, Common Lisp, and Java very well.

Striking a good balance between practicality and having fun is not so easy to do.

Some people say mathematics is beautiful. After several years, unfortunately, I could never see that beauty. There was a point, long ago, where I could see the beauty of Forth.

Ditto with Bach. On the other hand, I 'get' the beauty of Beethoven and the Boards. To each his own ... but 'beauty' is de gustibus, and mere functionality does not qualify.

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