We're hiring!

We're actively seeking designers and developers for all three of our locations.

Why Haskell Is Worth Learning

When I recommend learning Haskell to the uninitiated, I often get asked: “Why Haskell?” “Is it a practical language?” and “Is it something I can actually use?” My answer is definitely yes.

Haskell isn’t my primary language at work (I mostly write C code for embedded systems), I’ve still found it incredibly useful. And even if I never used Haskell at work, I would still consider learning it as time well spent. So, why Haskell?

1. Haskell Plays Well with C

It turns out Haskell is a very powerful tool for helping you write C. Haskell has let me do things I would normally not even consider to be, umm, practical.

Say one of my coworkers wants to find all the places in a legacy codebase that a variable foo is used in the conditional of an if. Thanks to the awesome language-c library and Haskell’s generics, I can write a Haskell function that takes the path to a preprocessed C source as input and outputs the source locations (if any) like so:

parseAndFindFoos :: FilePath -> IO (Either ParseError [Position])
parseAndFindFoos path = liftM (fmap findFooLocations) (parseCFilePre path)
 
findFooLocations input = fmap posOf (listify isIfOfInterest input)
isIfOfInterest (CIf cond _ _ _) = not (null (listify isFooIdent cond))
 
isFooIdent (Ident name _ _) = name == "foo"

Not including the type signatures, that’s just 4 lines of Haskell! The type signatures are usually inferred anyway, but it’s customary to include them as doc strings.

This is just a blog-post-sized toy example. I’ve I use Haskell to do far more complicated things, like extracting the names and types of functions and global declarations or performing a transformation that inserts bounds checks or logging functions in expressions that match certain criteria. There are not many other languages that would let me do this as succinctly and quickly as Haskell does.

I’m Not the Only One Making Tools for C in Haskell

One of my coworkers made an awesome tool called plunge that lets you compare preprocessed code c with the original and shows what each line in the original was processed into in the preprocessed version.

There’s also:

  • atom – A DSL that performs compile-time task scheduling and generates code with deterministic execution time and constant memory.
  • copilot –  A stream (i.e., infinite lists) domain-specific language (DSL) in Haskell that compiles into embedded C.
  • ImProv – An imperative programming language for high-assurance applications. ImProve uses infinite state, unbounded model checking to verify programs adhere to specifications.

And many others.

2. Haskell Changes the Way You Think

I really think the most immediately practical side effect *snirk* of learning Haskell is that it forever changes the way you think about code. Yes, yes, I know this sounds like warm, fuzzy, vague BS, but I’m serious! Learning Haskell has had more of an impact on the way I code, and the way I think about code, than anything I learned in school and any of my on-the-job experience.

Have you ever tried to write a complex function without using any mutation? At first it’s quite painful. But once you get some practice, not only does it get much easier, but you start realizing that your functions can get broken apart into much smaller pieces than you originally thought possible. That complex function will turn out to be not all that complex at all; it can be written as just three simple functions composed together!

It’s like if you only played soccer with your right foot. And then one day your coach forbids you from using your right foot. At first you suck at everything. But eventually you become just as good at using your left foot as your right, you and end up being a much better soccer player.

Haskell is so different that it forces you to think about your code differently. This is part of why it’s a hard language to learn, but also why learning it is so advantageous.

3. Haskell’s Steep Learning Curve Is a Good Thing

The most common complaint people have when learning Haskell is the steep learning curve. And they’re right, it does have a steep learning curve. It’s like learning programing all over again. It takes a bit to unlearn the patterns you instinctively want to use. No mutation! Static Typing! OMG they’re passing the value returned from that function as one of its arguments! WTF is going on!?

The hard part about learning Haskell is not the complex things, it’s the simple things. Like Monads; Monads are ridiculously simple. They’re just a datatype with an instance implementation of two very simple functions. Most implementations are just one or two lines! It’s the comprehending the implications, usefulness, and power of these very simple things that takes so much work. Profound things take time to learn. This is ok. It means you’re learning something that’s worth learning.

“Do you want to be locked into tricycles because they’re easy to learn?” – Douglas Englebart

 

Job Vranish (30 Posts)

This entry was posted in Functional Programming and tagged , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

14 Comments

  1. Posted March 5, 2013 at 12:33 pm

    Any recommendations for resources for learning it ? I started off with Learn You A Haskell, it made my head hurt, is it a good starter and I just have to persevere ?

  2. Mauzac
    Posted March 5, 2013 at 1:49 pm

    Just a tidbit.
    You used “it’s” (“it is”) where you should have used “its”:
    “OMG they’re passing the value returned from that function as one of it’s arguments!”

  3. Andy Adams-Moran
    Posted March 5, 2013 at 2:45 pm

    I’d also recommend looking at FP Complete’s School of Haskell. Lots of great tutorials, no signup required, edit and run Haskell code in your browser. Bartosz Milewski just put up one about monads and laziness.

  4. julian
    Posted March 5, 2013 at 5:50 pm

    So show us how to do simple things in it :)

    I mean… give illustrated comparisons between the language and others. Real world things, not academic things.

    The other day I had to build a thing that would tell me which points in an array of points were changing direction (where here, changing direction means changing its slope direction on the y axis).

    This is what I came up with in ruby:
    # array_under_question is an array of Point objects, which have an x and a y attribute
    array_under_question.each_with_index.each_cons(3).inject([]) do |change_point_indexes, ((point_1, _), (point_2, this_index), (point_3, _))|
    first_pair_direction, second_pair_direction = (point_2.y point_1.y), (point_3.y point_2.y)
    (first_pair_direction != second_pair_direction) ? change_point_indexes + [this_index] : change_point_indexes
    end

    This struck me as intensely convoluted and that only people quite well versed in ruby would be able to understand it. Is the equivalent easier to understand in haskell?

    • Long
      Posted March 5, 2013 at 9:06 pm

      I wrote a step by step translation of your Ruby code to Haskell, have a look: http://hpaste.org/83550.
      Note that this is just one way to do it and that you don’t have to write out the type annotations, which I just added because they help me understand the program.

    • Posted March 6, 2013 at 4:31 am

      Here’s an example in more idiomatic haskell:
      https://gist.github.com/jhickner/5098031

      The focus is really on function composition and successive, simple transformations to get to what you want.

  5. John Croisant
    Posted March 6, 2013 at 9:26 am

    Learning Haskell has had more of an impact on the way I code, and the way I think about code, than anything I learned in school and any of my on-the-job experience.

    Job, were you familiar with Lisp (any variety) prior to learning Haskell? Many programmers say that learning Lisp also changes the way they think about code. I’m curious if learning Haskell after Lisp still gives that mind-expanding benefit, and likewise for learning Lisp after Haskell.

    My gut feeling is that it probably does, because Haskell and Lisp are mind-expanding in different directions. I’d love to hear from someone who has learned both, in either order.

    • Scott Vokes
      Posted March 6, 2013 at 9:55 am

      In my experience, yes. Common Lisp and Scheme have taught me different things than my time with Haskell so far. Haskell overlaps more with the things I learned from OCaml, but emphasizes laziness quite a bit more.

  6. GDFrank
    Posted March 6, 2013 at 11:01 am

    Not taking away from Haskell (played with several functional models over the years) … but

    How would Haskel compare to F# … and would it make sense to “learn functional programming” in F# if you were a dotnet-er?

    How would the Haskell versus F# experience differ?

    You mentioned “embedded” … have you looked at Hume?
    http://en.wikipedia.org/wiki/Hume_(programming_language)

    .. or the other versions?
    http://en.wikipedia.org/wiki/Haskell_(programming_language)

  7. Mark Pawelek
    Posted March 6, 2013 at 11:29 am

    The MOOC courses I’ve done online have been worthwhile. Two Coursera courses :

    Functional Programming in Scala ( it is “in Scala” and about Scala but it covers functional programming.
    Programming Languages ( 4 weeks ML, 2 weeks Racket + Ruby )

    These will give you a much better idea of what thunks, laziness, closures, currying, etc are than any book I’ve seen. By and large, books concentrate on syntax but ignore semantics – bad, because a lot of FP languages share a fair amount.

  8. agatone
    Posted March 7, 2013 at 7:08 am

    The most common complaint people have when learning Haskell is the steep learning curve.
    Why would anyone have problem with steep learning curve?

    Maybe a good starting point would be to learn first what steep learning curve is … http://en.wikipedia.org/wiki/Learning_curve

  9. feng
    Posted May 25, 2013 at 11:33 pm

    more on language-c would be nice.