As somebody who has only recently started looking into functional programming, this was absolutely fascinating.
Even though I'm not very familiar with Haskell, I find this code much more concise and easy to follow compared to the original git-clone implementation in C. Though perhaps that's more down to the author's coding style?
As to your question, I think it is both. The author's ability to walk you through his thought processes in a clear and concise manner, his general strength as a writer, the fact that he added diagrams and models to help the reader, and that this did not seem to be written only for Haskellers to read... well they all add up to what you are describe. Kudos to the author.
I'm having an interesting experience with this at my job ... Haskell appears to be MUCH more approachable when you understand the problem at hand.
So much Haskell pedagogy wants you to write a compiler or a parser or ... whereas this article is taking you through a solution. And whaddyaknow -- Haskell comes across as gorgeous, elegant, compact, and highly comprehensible.
When I show a FIX server or REST API written in Haskell to a non-Haskeller coworker (ie everyone else :) ), with minimal explanation they're getting what's going on. I look forward to many more "Haskell-in-anger" articles to show the world how fantastic it is to work with.
Yes. Haskellers are just too much in love with compilers and parsers. Those are much easier to write in Haskell, but not enough people have grappled, and suffered (and failed) to write one in eg C to appreciate.
In my experience, pure functional programming, combined with Haskell's relatively permissive syntax, allows for very natural-language-like and well-structured programs.
Languages like Agda can do this even more impressively. You can do stuff like write
if_then_else_ : Bool -> a -> a -> a
And you can split up the "if", "then", and "else" and put the arguments where the underscores are.
Meh. I think it is arguable that the code from this article is as easy as it is to understand as much from the prose that goes with it as from the language it is written in. My argument would actually lean towards more so.
> I think it is arguable that the code from this article is as easy as it is to understand as much from the prose that goes with it as from the language it is written in.
Apologies. I think I should have just written that in multiple sentences. I don't think mere commas can save it.
Simply put, my assertion is that it is the accompanying prose and diagrams that truly make the code easy to understand. Not its implementation language.
I would love to say that my terrible sentence above illustrates that prose is not a panacea. Well, I think I can claim that. I can not claim it was intentional. :)
> Simply put, my assertion is that it is the accompanying prose and diagrams that truly make the code easy to understand. Not its implementation language.
Haskell does help somewhat, in that it's offers you a lot of flexibility in how to structure your program. So you can tailor your program to your explanation. (Knuth's literate programming tools help bring those capabilities and more to more conventional languages.)
The underscores are placeholders for arguments, just like in Agda, but there's no name defined! Since `0` and `1` are defined as constructors of `Bit` (which is a sub-type of `Bits`) this will parse values like `0101010` as `Bits`.
But the if_then_else_ example is basically smalltalk equivalant - although I suspect Agda will be able to do without the angle brackets that Smalltalk often needs in these cases.
That is indeed the case. In Agda, the default is call-by-name, which means that functions are applied before arguments are evaluated. This does not, however, include sharing, so evaluating
(λ x → x + x) (fib 2000)
will evaluate `fib 2000` twice. Agda programs can also be compiled to Haskell, in which case they would have Haskell's evaluation strategy, which is generally call-by-need (and so would share the result of fib 2000 above.)
Even though I'm not very familiar with Haskell, I find this code much more concise and easy to follow compared to the original git-clone implementation in C. Though perhaps that's more down to the author's coding style?