This is actually pretty helpful, in that my approach to programming in a new language is "Try to do X with the new language, and if I can't, read the docs until I can." That is, I try to actually DO something, and gather incidental knowledge along the way.
This is a really good post on how to do something useful with Haskell (plus it has IO, which is nice). One of the nice things about this approach is that the incidental knowledge can be useful, e.g. I didn't know about the "-e" flag to GHC.
Most of these things are basically just aliases, partial applications and/or compositions. It shows off how powerful Haskell is and it is impressive but that's pretty much it.
I'd much rather see how you tweet something from Haskell, parse a configuration file with a simple syntax or something else along those lines.
Looks like the tail implementation is O(N) in the size of the file. Real tools aren't (for large N anyway), and as this is a basically iterative algorithm (guess at a suffix size, read, count, adjust) it seems like it might have been more instructive here to do it right instead of doing it pretty.
These aren't "real". They're "simple". It's right there in the title. You're suggesting making it a good five or ten times more complicated, and you'll still be left with problems like how not a single one of the other things there is "real" even after you've fixed tail. I'm not even sure why you chose that one in particular to focus on when grep is useless, tr only allows on substitution, uniq is bounded by memory... but the point is they are simple.
There's a spectrum between "simple" and "wrong" though. I thought grep/uniq/tr were fine, as a correct implementation would be a straightforward extension of the code presented (well, the size bound on uniq is real, but swap storage is free these days so who care?).
The tail example wasn't like that. It's the wrong algorithm. It's also in a class of algorithms that's particularly difficult in functional languages.
Showing easy examples and skipping the hard stuff, IMHO, is endemic with "enthusiast" languages like this. I don't think that shows the language in a very good light.
Shouldn't they be using Data.ByteString instead of the standard Haskell string?
Otherwise any newbie running this code will come back crying: "it's slower than my simple python implementation" (not to mention the standard GNU tools).
The goal here is simplicity, above all else. (I would recommend Data.ByteString.Lazy, though, if you're interested in processing potentially large files without running out of memory.)
13 comments
[ 3.3 ms ] story [ 40.8 ms ] threadThis is a really good post on how to do something useful with Haskell (plus it has IO, which is nice). One of the nice things about this approach is that the incidental knowledge can be useful, e.g. I didn't know about the "-e" flag to GHC.
I'd much rather see how you tweet something from Haskell, parse a configuration file with a simple syntax or something else along those lines.
* http://hackage.haskell.org/package/twidge * http://hackage.haskell.org/package/ConfigFile * http://hackage.haskell.org/package/EEConfig * http://hackage.haskell.org/package/dyre
Hmmm... I mean that somewhat less vacuously than English is rendering it.
The tail example wasn't like that. It's the wrong algorithm. It's also in a class of algorithms that's particularly difficult in functional languages.
Showing easy examples and skipping the hard stuff, IMHO, is endemic with "enthusiast" languages like this. I don't think that shows the language in a very good light.
Otherwise any newbie running this code will come back crying: "it's slower than my simple python implementation" (not to mention the standard GNU tools).