This reminds me that when I was interested in learning haskell I was completely put off by their "introduction" page on their homepage. It was a couple of years ago but it doesn't seem to have changed much:
It looks like a very pretentious sales pitch to me. You have quotes like "Writing large software systems that work is difficult and expensive. [...] Functional programming languages, such as Haskell, can make it easier and cheaper." and a whole bunch of very vague and poorly backed up assertions.
After a couple of paragraphs brainwashing you about how good functional programming is, you finally get to some code. The first code you get is (of all things) a quicksort which is not used as an introduction to the language but as a way to boast that haskell is so much better and more expressive than C. I mean, look at that C code just after it, disgusting isn't it.
What they don't say is how much slower their implementation is, of course. They also give a link to a more direct (and faster) C-to-haskell version of the quicksort[1]. Hey, it's actually longer than the C version! And it uses 3 imports. And it's still slower than the original C. Oops. I wonder why they didn't put that one in the tutorial. I went back to common lisp after that, I have yet to write 1 line of haskell.
TL;DR: when I want an introduction to your language, I want to know what I can do with it and how I can do it. Give me some code to chew on, show off some features. Don't spend 10 pages telling me you're the best of the best and everything else is crap. This is the kind of article I expect: http://perldoc.perl.org/perlintro.html
That wiki link to an actual implementation of quicksort in Haskell is pure comedy gold (1):
"Unfortunately none of the above "real" quicksorts seems to compile as given"
"The program below is working very very slowly. It's probably slowsort."
"A more specific/direct translation (neither this nor the C version is polymorphic) is offered by Daniel Fischer, who reports that this version runs within 2x of the C version"
(and it's a completely unreadable mess that is clearly a line by line copy of the C code given)
To be fair, QuickSort is particularly suitable for imperative languages that allow in-place modification of arrays. For functional languages, merge sort is a much more natural solution that is simple to implement, guaranteed to be efficient, and probably reasonably fast (though still unlikely to beat a QuickSort implementation in C).
To be fair, QuickSort is particularly suitable for actual computation hardware which has hardware features like numerically addressed, stateful random access memory. Imperative arrays happen to feature "in-place modification of arrays" not because it's a useful language feature but because it's a straightforward abstraction of the actual machine being programmed.
That distinction is really important, and something I think many language nerds completely fail to understand. Sure, often all that's "really" important is the abstraction of the "Human Design Space" idea being implemented, and that's a regime where high level language abstractions have lots of value.
But sometimes you want to actually direct the hardware. And there, as everywhere, it helps to use a language with the proper abstractions. C has them, Haskell doesn't. There's absolutely no shame in that!
But somehow people get fooled into thinking that somehow Haskell (or whatever language is involved in the argument, but it seems like Haskell people fall into this hole more than most) doesn't need those abstractions to be "as fast a C". And that's just insane.
To be fair to mergesort, it's particularly suitable for actual computation hardware too. It's mostly linear reads and writes, which almost all i/o systems heavily favor. GNU sort uses mergesort (in C).
GNU sort is designed to sort on disk though. If you actually watch it working on a giant file, you'll see it generating lots and lots of files in /tmp containing the merge lists.
This is because quicksort obviously requires fast random access to the whole arrays, and (at least when it was written) /usr/bin/sort would be expected to be able to quickly sort data that can't fit in memory.
So... if anything I think this is evidence to my point: in the performance regime, you have to match the algorithm choice to the hardware. Specifically here: sort is making up for the lack of memory by exploiting the comparatively (relative to virtual memory) fast streaming behavior of storage media.
Notably, stateful filesystem I/O is also an area where Haskell tends to fall down. I'm not at all sure a Haskell merge sort of the form used in GNU sort would do well at all, though I'm willing to be proven wrong.
> GNU sort is designed to sort on disk though. If you actually watch it working on a giant file, you'll see it generating lots and lots of files in /tmp containing the merge lists.
The number of files created is just an implementation detail; you could easily do everything in one file if you wanted to, or at most 2N files if you're not allowed to seek or overwrite files at all, and you want to do N-way merges.
Maybe GNU sort is just trying to avoid creating files larger than 2 GB (which is a problem on legacy file systems).
> Specifically here: sort is making up for the lack of memory by exploiting the comparatively (relative to virtual memory) fast streaming behavior of storage media.
Yes, also the fact that GNU sort can sort multi-terabyte files on 32-bit platforms, which otherwise wouldn't fit in memory. (Though systems with smaller process memory space than disk storage space are an oddity that will soon be outdated, I suppose.)
> I'm not at all sure a Haskell merge sort of the form used in GNU sort would do well at all
Well, even the on-disk sort starts by sorting chunks in-memory, which we have already established Haskell is bad at. However, the merge sorting part of the algorithm may well be I/O bound in practice, in which case Haskell should be able to do it just fine.
The only good reason I can think of why C could be faster, is that if you can merge more efficiently, you can choose a higher value of N for your N-way merge,
> stateful filesystem I/O is also an area where Haskell tends to fall down
What do you mean by this? AFAIK Haskell can read/write files just fine through the I/O monad.
It is linked from the main page to answer the question "What is Haskell?" It is not supposed to an example driven page at all. The title of the wiki page could be changed to fix this though. The very next link is http://tryhaskell.org/ to learn Haskell in a example driven way.
Looks like what I would expect from a language introduction. Explains the syntax, shows off some features, gives you snippets of code and tells you how to feed them into a REPL. It's a good way to start and get people interested in the language I think.
Plus quicksort is a classic morass- by the time you harden it enough to deal with real world data you could have written a proper merge sort with similar average case performance and much better worst case guarantee. My rant on quicksort: http://www.win-vector.com/blog/2008/04/sorting-in-anger/
Interesting read, thanks for linking it. When I need to write a sorting algorithm, I usually for Merge Sort, because I can never remember the exact details of swapping/partitioning of QuickSort. It seems much more natural to say "split your data in two, sort them, merge them together". And when I'm feeling damn fancy, I use an InsertSort when the size of the dataset is less than 7-8, another algorithm that I find difficult to forget (at least, the recursive definition; I usually need some paper and pencil to do the in-place version).
That is not the best introduction to the programming language by means of practical examples, but it does not look like it is supposed to be either. At least from Haskell.org it links from "What is Haskell?" Which is a very different question then what can I do with Haskell.
> After a couple of paragraphs brainwashing you about how good functional programming is, you finally get to some code.
Whenever I see a page about a new programming language I usually skip all the marketing speech at first and look for a code fragment to examine first. After that I'll start reading the actual text.
"They also give a link to a more direct (and faster) C-to-haskell version of the quicksort[1]. Hey, it's actually longer than the C version! And it uses 3 imports. And it's still slower than the original C. Oops"
that made me laugh a few years (?) ago and it still does :)
the question was "a good sized working program", the racket page is a great page but only has a few haikus, so "no" should be your first word, even if the rest of the comment is correct :)
http://www.haskell.org/haskellwiki/Introduction
It looks like a very pretentious sales pitch to me. You have quotes like "Writing large software systems that work is difficult and expensive. [...] Functional programming languages, such as Haskell, can make it easier and cheaper." and a whole bunch of very vague and poorly backed up assertions.
After a couple of paragraphs brainwashing you about how good functional programming is, you finally get to some code. The first code you get is (of all things) a quicksort which is not used as an introduction to the language but as a way to boast that haskell is so much better and more expressive than C. I mean, look at that C code just after it, disgusting isn't it.
What they don't say is how much slower their implementation is, of course. They also give a link to a more direct (and faster) C-to-haskell version of the quicksort[1]. Hey, it's actually longer than the C version! And it uses 3 imports. And it's still slower than the original C. Oops. I wonder why they didn't put that one in the tutorial. I went back to common lisp after that, I have yet to write 1 line of haskell.
TL;DR: when I want an introduction to your language, I want to know what I can do with it and how I can do it. Give me some code to chew on, show off some features. Don't spend 10 pages telling me you're the best of the best and everything else is crap. This is the kind of article I expect: http://perldoc.perl.org/perlintro.html
[1] http://www.haskell.org/haskellwiki/Introduction/Direct_Trans...