Translate Haskell into English Manually, Part II
I really hate to spoil the tone of such a nice tutorial with opinionated commentary, but the exceedingly careful reader may have noticed that the C version is shorter than the Haskell version! In fact, by my count, there are 106 useful lines of code in the C version and 146 lines of useful code in the Haskell version. What happened? This is the type of thing that can make a budding article writer lose sleep at night!
Notice a few things. The C version is using static memory allocation. It pre-allocates space for 100 tokens, each of which can be up to 64 characters long. Modern C applications must usually manage memory dynamically, and it's a painful, error-prone chore. Nor does the example do any error handling. Haskell's exception system went completely unused. Last of all, the example didn't make use of any abstractions. Haskell's high-level, functional nature means that libraries, in general, can be higher level in Haskell than in C, but this is meaningless if you don't even use a parsing library.
Note, however, that the Haskell version already has some benefits over the C version. For instance, being able to print a ParseContext for free was really nice. Theoretically, because all parsing state is contained in a ParseContext, you can pass off the ParseContext to another machine and let it continue the computation. If, during parsing, for some reason it was necessary to undo what you had done and go back to some previous parsing state, it's absolutely possible to throw away your current ParseContext and continue with some previous ParseContext.
Consider the task of removing a bolt. You have your choice of a crescent wrench (say, C), a socket set (say, Java) or an impact wrench (say, Haskell). An impact wrench is incredibly powerful and can make difficult tasks easy. However, what we've seen is that sometimes it takes longer to retrieve the compressor from the garage in order to use an impact wrench than it takes to simply get the job done with a crescent wrench.
If Haskell is so powerful, why isn't it more popular? I think it's because the authors and many of the users are just too dang intelligent! I've heard Guido van Rossum, the author of Python, say something like, “ML is a great language--it's just too bad you have to have an IQ higher than 150 to use it.”
Consider that in Paul Hudak's book, The Haskell School of Expression, Hudak drags the user through writing code to calculate the area of a concave polygon [exercise 2.5 on page 33] before he even shows the user the canonical “Hello world” example [page 37], and I still haven't gotten to the part in the book that explains how to use Hugs. [Note: I'm being facetious. I don't think it's covered in the book at all. Hugs is an implementation of Haskell, and the book is about the language itself, not any particular implementation. However, my point stands that unless you actually get an interpreter or compiler running so that you can actually write some code, you can't truly claim to know a language. I spent hours trying to figure out why the Hugs shell wouldn't let me define a function before I found out that you have to store them in a file and load them as a library.]
Furthermore, as much as I love Haskell's type system, I think there's a real misconception. Hudak writes:
The best news is that Haskell's type system will tell you if your program is well-typed before you run it. This is a big advantage because most programming errors are manifested as typing errors [p. 8].
I don't agree. Although I would agree that most bugs are caused by programmers typing the wrong code, I would not agree that most bugs are manifested as typing errors! In fact, I find that most of my bugs are caused by subtly misunderstanding the fine details of a difficult problem, and I've heard other well-respected programmers say the same thing. Personally, being a fan of duck typing, I find that most of the time, types are almost a nuisance! [Note: Lest Java programmers send me hate mail, this is a topic covered repeatedly by Bruce Eckel, author of Thinking in Java, on his blog (mindview.net/WebLog/ArticleIndex). For instance, this post: mindview.net/WebLog/log-0025. If you consider tools like QuickCheck (www.cs.chalmers.se/~rjmh/QuickCheck), which can use Haskell's type system to generate test cases automatically, you'll see that a whole article could be written debating whether Bruce Eckel's ideas apply to Haskell. Nonetheless, I think it's fair to say that Haskell's type system gives you “more bang for the buck” than Java's.]
I spent a lot of time wondering why Haskell programmers seemed to be so successful. I've come to the following conclusion:
It's not that good programmers are necessarily drawn to Haskell--as Google has shown, there are a lot of extremely talented programmers who are content to code in Java. Rather, it's that you have to be a smart, patient, disciplined and dedicated programmer to code in Haskell at all.
The truth of the matter is you can be a bad programmer and make a living coding in Java. The same cannot be said of Haskell.
In summary: I think that it's fair to say that Haskell has some flaws (for instance, you have to be smart to use it), and it might not ever be as popular as Java, PHP or Ruby. However, languages are like friends; you take the good with the bad and enjoy them as a whole (with the exception of C++; almost no one uses all of C++).
Haskell is like a brilliant kernel programmer I once worked with. Asking him anything outside his areas of expertise was like trying to dereference a random location in memory. I use to joke that his user interface was about as friendly as a Commodore 64--“syntax error”. Nonetheless, you just couldn't beat him if you needed a new device driver for some random piece of hardware. Likewise, if I had to reimplement Pascal or write Perl 6, Haskell would be my first choice--although I'd definitely use a powerful parsing library. In fact, I'm pleased to say that Haskell is a welcome addition to my programmer's toolbox!
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Reply to comment | Linux Journal
1 hour 12 min ago - Reply to comment | Linux Journal
1 hour 28 min ago - Favorite (and easily brute-forced) pw's
3 hours 19 min ago - Have you tried Boxen? It's a
9 hours 11 min ago - seo services in india
13 hours 42 min ago - For KDE install kio-mtp
13 hours 43 min ago - Evernote is much more...
15 hours 43 min ago - Reply to comment | Linux Journal
1 day 29 min ago - Dynamic DNS
1 day 1 hour ago - Reply to comment | Linux Journal
1 day 2 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
Good static typing does make a gidfference.
As background: my first five years of full-time programming were Java, the next five years after that, Ruby, and over the last year or so I've moved to nearly-full-time Haskell.
Types in Haskell do often feel like a nuisance when you come from a Ruby background, especially when you're doing quick-and-dirty hacks where you're not so concerned about correctness because you're going to throw out the code after a few uses.
However, these days I just as often find the lack of types in Ruby to be more of a nuisance because I have to work fairly hard to keep silly bugs from creeping into my programs (oops, that was supposed to be an array of arrays, not an array) whereas in Haskell the type checker deals with all of this for me. In Haskell I find myself using far fewer unit tests and doing both small and large refactorings with more confidence. I also find I no longer need to use error checking code as I did on occasion in Ruby, where I'd look at a situation and say to myself, "if the wrong class of object gets out of here, it's going to appear half-way across the program and I'll spend ages debugging it."
Not to mention which, when you really start using monads and combinators, you'll find them extremely powerful.
cjs@cynic.net
it's unfair to blindly translate algorithms
Brandon Moore has sent me an alternate version of the code that is both simple and yet still shorter than the C version. His findings suggest that an algorithm in C may not translate easily or naturally into Haskell; which, of course, is not surprising. I purposely made the Haskell program as close to the C program as possible to aid the reader in understanding it, but perhaps this was an unfair handicap to Haskell.
Alternate solution
I wrote some alternate code which makes a simple parser monad, rather than the simple state monad used in the article. It's like a recursive descent parser, but with all the recursion wrapped up inside the monad. This doesn't quite handle quantifiers like const and static at the beginning of the declaration correctly, but the C and Haskell code are already both wrong in different ways, and the full syntax is really complicated so I don't care. I count 62 lines of code.
Many thanks for a very clear
Many thanks for a very clear tutorial. I'm some way from grokking monads but this should help...As you say, introductory articles on monads are usually a bit deep (The subtitle of the Programmers Guide to Monads, 'Don't Panic', sounds promising but 2 or 3 pages later sure enough I was panicking!) so congratulations on not mentioning Category Theory :-)
Your link to the syntax tour is broken. I suppose it's meant to be http://www.cs.uu.nl/~afie/haskell/tourofsyntax.html but that gives a 404 - another place is http://cs.anu.edu.au/Student/comp1100/haskell/tourofsyntax.html but I don't know if this is it's home.
thanks
Thanks for your comment as well as mentioning the broken link.