Skip to content
July 29, 2007 / cdsmith

37 Reasons to Love Haskell (playing off the Ruby article)

Here’s an article on reasons to like Ruby.  It’s actually very well written and persuasive.  So I took it as a challenge.  How well would Haskell fare when compared against this specific set of criteria, changing the points as little as possible?  The meanings will inevitably shift a bit, and readers will know that Haskell has its own set of advantages, of course.

The point of this exercise, though, is to see how Haskell does in the benefits mentioned for Ruby in that particular article.  It’s not a Haskell vs. Ruby; just a shameless theft of a set of criteria.  Should be fun.

  1. It’s object oriented.  Although it wasn’t designed for it, this paper points out that Haskell scores pretty well in support for object oriented programming features.  It’s not entirely clear that this is a good way to write code; but if it isn’t, it’s not because Haskell doesn’t provide the features or support you need to make it work.
  2. It’s pure. Haskell chooses to be pure in the functional sense, rather than the object-oriented sense.  The same ideas remain, though; there are no messy bits that don’t fit into the prevailing mode of thought.
  3. It’s a dynamic language. Yep, you heard right.  Projects like Yi and hs-plugins and lambdabot prove that it’s quite possible to write programs with runtime code loading and manipulation and other dynamic features in Haskell.  Indeed, the type system gives you a level of assurance that you haven’t made big mistakes along the way; something that’s quite likely when assembling code at runtime from many small pieces.
  4. It’s an interpreted language. Honestly, I’m having trouble understanding this point in the original; the Ruby article doesn’t ever say why this is a good thing.  It helps, of course, in that it lets you work with the program interactively, easily trying out bits at a time rather than having to write a new main method to do any testing.  Unlike Ruby, Haskell can also be compiled to handle any performance concerns; combining the advantages of both worlds.
  5. It understands regular expressions. The Text.Regex module in the Haskell standard library contains functions to do regular expression stuff.  It even uses Haskell’s operator mechanism to define operators like =~ to look more like other languages sometimes.
  6. It’s multi-platform. GHC, the major Haskell compiler, exists for Linux (many processors and distributions), Other UNIX-like systems (FreeBSD, NetBSD, OpenBSD, Solaris), many Windows variants (95 through Vista), and MacOS (Intel and PowerPC).  Nobody cares about MS-DOS :).
  7. It’s derivative. Haskell as a language borrows many of the best features from other languages, especially ML (its type system), and Miranda (its evaluation order).  It borrows libraries from lots of places.  There are Haskell bindings for wxWindows and GTK+, for example.  And yes, printf, too.
  8. It’s innovative.  If there’s any single widely used language today that has a claim to being truly innovative, it’s Haskell.  Haskell is practically a research playground, while still managing to be a practical language.  New language features have been the bread and butter of its progress: type classes, monadic I/O and computational environments; more recently: GADTs, associated types.  All of these are rare in other languages.
  9. It’s a Very High-Level Language (VHLL).  I actually doubt this term has any kind of meaning at all; but if it does, then Haskell has quite a good claim to fitting its meaning.  To the extent that the high/low level language distinction is meaningful, it’s about the ability of software to transform the program from something that’s useful to programmers into something that’s efficient and executable on machines.  More work is going on here in Haskell (e.g., see the Data Parallel Haskell project) than in any other language I’m aware of.
  10. It has a smart garbage collector.  I’m not sure this should even be worth a mention on the list.  Languages without automatic memory management are simply not candidates for writing serious application level code in the modern world.  For what it’s worth, though, yes Haskell does it.
  11. It’s a scripting language. Despite having virtually none of the properties that conventional wisdom associates with scripting languages, Haskell is quite usable for scripting.  Function composition and the monadic >>= operator provide the ability to combine pieces every bit as tersely as pipes; type inference eliminates the cost of static types.  This page talks about using Haskell for scripting, and this one describes the -e option to ghc, which lets you run Haskell code directly from the command line, and gives an example of using it.
  12. It’s versatile. As a general purpose programming language, you can do as much with Haskell as practically anything.  Scripting is simple, as described above.  Haskell also has a very advanced application server letting you write complex web applications; has been used to write a very nice window manager, is widely used in financial and other industries, and has been used to implement other languages — itself and the very first implementation of Perl 6.
  13. It’s thread-capable. And more!  There are basically two languages worth looking at for modern concurrent programming: Erlang and Haskell.  Haskell implements not just multithreading, but three different higher-level abstractions on top of multithreading: Software Transactional Memory, Data Parallel Haskell, and basic Parallel Haskell.  All three provide tools to make it easier to build correct threaded programs.  (Of course, Haskell offers less interesting traditional concurrency abstractions as well.)
  14. It’s open-source. All Haskell implementations have the source code fully available.  The major people involved hang out and regularly respond by both mailing lists (newsgroup interface available, too) and even IRC channels.  Haskell has one of the most famously open and friendly communities around, so you’ll fit right in!
  15. It’s intuitive.  Haskell doesn’t have a shallow learning curve, but that’s because you’re really learning things; not just learning a new syntax for the same programming you’ve done for years.  Haskell stays out of the way and lets your mind be expanded by the concepts you’re seeing instead of by the arbitrary choices of the language implementors.  That’s about as intuitive as you can really ask for.
  16. It handles exceptions well.  Unlike practically any other language, Haskell does the right thing for computations that have exceptional cases.  When working in a purely functional way, it gives you simple types like Either and Maybe that help to express those exceptional conditions in a functional manner.  When you’re working in an imperative way (e.g., in the IO monad, or any other MonadPlus environment) it provides exception handling, since that’s the right choice for the imperative style.
  17. It has an advanced Array type.  You don’t have to declare types at compile-time, or allocate memory in advance, or keep up with their length, or worry about indexing out of bounds (unless you explicitly choose to use unsafe operations).  Unlike many other languages, though, arrays aren’t syntactically preferred.  It’s just as easy to use a map, list, sequence, or many other things depending on what best suits your application.
  18. It’s extensible. You can write external libraries in Haskell or in C.  You can declare new instances (in other words add new behaviors to existing type signatures; gives you the core benefit of modifying existing classes) on the fly.  You can also add new operators (and I do mean new operators, not rehashing a very limited set of operators in error-prone ways like you do in C++) and use monads to define whole new computational environments if you like.
  19. It encourages literate programming. Even if you aren’t really doing literate programming, you can embed comments in your code which the Haddock tool will extract and manipulate.  You can look at type information even if it was never documented at all, simply by asking GHCi or Hugs for the type.  If you’re really into literate programming, though, major Haskell compilers understand literate source files that default to comments, and only include code delimited in specific ways (birdtracks, or latex begin/end commands).  This lets you, quite literally, compile the same document into either executable code or a details PDF user manual, without even having to do anything unusual to your latex source!
  20. It uses punctuation and capitalization creatively. Haskell enforces a punctuation scheme that makes the meaning of code clearer.  Types, classes, modules, and data constructors begin with upper-case letters.  Variables (including type variables) start with lower-case letters.  Fortunately, though, a lot of very important information is stored in the type — including, for example, whether a function result is Boolean or not, and even whether it destructively updates something!  This information is available at your fingertips either by reading documentation or just by typing :t at the GHCi command prompt, so you don’t have to repeat it over and over again in your code.
  21. (Some) reserved words aren’t. Haskell has very few reserved words compared to most other languages, because the language itself is conceptually simpler (not to be confused with easier to learn, as mentioned earlier).  A few keywords aren’t reserved, but I can’t pretend that’s a good thing.
  22. It allows iterators.  More generally, higher-order functions are useful in a large number of situations.  When combined with lazy evaluation, there are a plethora of powerful techniques for handling collections of data in Haskell.  Iterators loosely correspond to maps and folds, which are well supported and widely used.
  23. It has safety and security features. Haskell provides as advanced a set of fool-proof safety and security features as is found in basically any language.  Its type system allows you to express security constraints (even rather generalized ones) in embedded domain-specific constructs that can be enforced by the compiler, so you never even attempt to run unsafe code!  If a new kind of security issue arises, it’s generally possible to use the powerful type system to solve the problem without waiting for language support for something like tainted data.
  24. It (really) has no pointers. Unlike the trivial sense in which languages like Java are claimed to have no pointers by restricting the most dangerous operations on them, Haskell really has no pointers.  (It’s worth noting that the Java language specification wasn’t fooled into the “no pointers” myth, as a peek as the second sentence of 4.3.1 in the 3rd edition spec will make clear.)  In a pure functional language, there’s no difference between using pointers and actual values, so the compiler can make the decision based on performance concerns, rather than exposing the distinction between pointers and data to the programmer.  This is part of Haskell’s being a higher level language.
  25. It pays attention to detail. This is one of those Orwellian newspeak things where the Ruby article I’m working from claims one thing (attention to detail) and then describes the opposite (extreme sloppiness).  Haskell follows the real attention to detail picture here, though you can define your own synonyms (for values or types) if you like.
  26. It has a flexible syntax. Haskell has a truly flexible syntax in ways that Ruby can’t dream of.  It allows programmers to embed domain-specific languages that are significantly and fundamentally different from the imperative model of Ruby.  Parsers can be written by embedding context-free grammars right into the source code.  Logic processing can be added by embedding Prolog-style inference rules into the language.  An infinite supply of operators are available to facilitate these languages.  Higher-order functions and monadic environments are available to make them work well.
  27. It has a rich set of libraries. Available libraries is one place where Haskell is way above practically all languages with similar community sizes, and in the ballpark of a lot of mainstream languages.  There are libraries for practically anything, including several for GUI programming, web programming, transactional persistence, and plenty else besides.  I wouldn’t want to try to list them all, so here.
  28. It has a debugger. Okay, so this is the biggest stretch yet.  The development version of GHC (to become GHC 6.8) actually does have a debugger; but the debugging tools for released versions of Haskell are sketchy at best.  This is improving.
  29. It can be used interactively. This is true in the sense that GHCi exists.  It’s less true in the sense that someone can use it as their login shell.  Yes, it’s possible; no, it’s probably not a good idea.  This is interesting, though.
  30. It is concise. Haskell code is about comparable to many scripting languages.  Sometimes it’s a little longer.  Sometimes (generally when one can make good use of powerful abstraction techniques like monads and higher-order functions ina  program of large enough size that it makes a difference) it’s a lot shorter.  The xmonad window manager is about 500 lines of code.
  31. It is expression-oriented.  As a purely functional language, of course it’s expression-oriented.
  32. It is laced with syntactic sugar.  Haskell’s got all sorts of nice syntax in ways that really matter quite a lot: custom operators and fixity declarations, do blocks for monadic computation, etc.
  33. It has operator overloading.  In fact, operator overloading in Haskell is far nicer than in most other languages, because you can make up your own operators.  No more confusing bit shifting with I/O.  Within a given context, an operator means a specific thing; but at the same time, it can apply to your custom types (ah, the magic of type classes) and you can make up your own different operators to do different things concisely.  Reading a journal paper that uses dotted relational operators to mean something?  Great!  Use them in Haskell, too.
  34. It has infinite-precision integer arithmetic.  It also has infinite-precision rational arithmetic, and fixed-precision types in case you want those, too.  And you can build your own types somewhat concisely.
  35. It has an exponentiation operator.  Actually, it has three!  This is because there’s a difference in what the three of them mean in some cases, so you get your choice.
  36. It has powerful string handling.  It does, but more importantly it also has powerful list handling, and these list handling routines are all usable on strings.
  37. It has few exceptions to its rules.  Haskell’s semantics are basically the lambda calculus.  The whole language is remarkably consistent and behaves in consistent ways.  The semantics are even simpler and easier to understand than any imperative language, which has to do with the distinction between values and variables; or eager languages, which have to deal with the question of evaluation order.  This makes Haskell programs very easy to understand and manipulate safely.

So there you have it.

28 Comments

Leave a Comment
  1. Gwern / Jul 29 2007 4:18 pm

    Pedantic note: remember that “it’s” expands to “it is”, and you use “it’s” very often where you meant the possessive “its”.

  2. cdsmith / Jul 29 2007 4:25 pm

    Fixed, thanks

  3. Rasmus / Jul 29 2007 4:57 pm

    Now go make 37 arguments in form of 37 code snippets :)

  4. Porges / Jul 29 2007 5:39 pm

    Sounds like a challenge :)

  5. diogo / Jul 29 2007 5:50 pm

    i was inclined to make a Lisp 37 list, but then i realizes it’s stupid, since Lisp has anything you would put in any other language’s list.

    besides, lists are stupid, anyway.

  6. she / Jul 29 2007 6:38 pm

    Main problem is the amount of syntax noise a language has.

    Take perl. It has a lot of syntax noise.

    With haskell and ruby, it too much depends on the coder in question.

    Python has an advantage here. Although it is worse than ruby ;) and probably haskell as well,
    its uniform militaristic attitude give it a very good advantage there.

  7. sorear / Jul 29 2007 7:26 pm

    3. All implementations of Haskell are recognisably interpreters. (Some of them, notably HBC and GHC, use dynamic specialization techniques to achieve very good performance, but they’re still technically interpreters.)

    6. Hugs supports DOS. Nhc98 supports palm-pilots. Yhc (with Golubovsky’s new backend) supports internet phones.

    10. Forget smart, it’s pretty much the most advanced in the world! Memory allocation is as fast as sequential writes; OOM checks are coalesced automatically; generations and parallelism are supported, with incrementality in an unmerged branch.

    24. But if you really, truly need them, you can get a safe (type-safe and unable to damage things outside of the current computation) version from Control.Monad.ST.

    28. Haskell supports Forth-style interactive experimenting, with the added benefit that purity makes it unnecessary to entire commands in the right order, reset states, or anything like that. It isn’t great, but it’s much better than most non-C languages…

  8. Tom / Jul 30 2007 12:49 am

    ” … besides, lists are stupid, anyway.”

    Said the Lisp fan.

    :)

    (BTW, you’re right about the Lisp part)

  9. Jessta / Jul 31 2007 7:14 am

    Every time I read an article like this I get the urge to try haskell again. But everytime I try haskell it’s quite confusing.

    The whole, ‘we don’t have state except that we do but we call it something else’

    GUIs have state, there is no getting around that.

  10. mm_freak / Jul 31 2007 6:31 pm

    I would like to note that Haskell has a very powerful and fast generalized exponentiation operator for integral exponents. If you define a new Num-instance (e.g. for modular arithmetic or more exotic things like elliptic curve groups), the exponentiation operator will be specialized to it automagically, and works just the way you would expect.

  11. p / Aug 7 2007 8:51 am

    Jessta: Haskell’s state management is just broken down to a little finer level than traditional imperative variable storage. You can program in that same style by using bind operators, but you also have the option of abstracting the state you keep track of to things like nondeterminism, while being assured that different states will compose sanely.

  12. Anonymous / Aug 24 2007 4:38 pm

    About point 28: Linux doesn’t have an anti-virus program. Haskell doesn’t have a debugger.

  13. Mike / Nov 3 2007 5:26 pm

    #27 is false.

    It’s really not fair to say that “Libraries” are a point in haskell’s favor.

    Most of the packages on Hackage will not build successfully on a recent GHC system, and there is no QA system for packages outside of GHC boot/base package set (core data structures).

    Also, despite several attempts and a work-in-progress (LambdaVM) there is not yet a functioning, easy-to-install bridge to Java/CLI or other langauges (just a DIY FFI to C), so the huge multiverse of Java/Python/Perl libraries are not effectively available to Haskell.

    Haskell can’t really be said to have real-world library support.

  14. Pierre / Dec 10 2007 10:20 am

    Amazing you manage to say that object oriented is the first reason to love Haskell.

    Sounds like everything is object oriented these days.

    What about trying to figure out what it means first ?

  15. Eduardo Costa / Feb 1 2008 6:17 pm

    I cannot understand why one uses Haskell, instead of Clean. I would appreciate to hear arguments for using Haskell, when one can use Clean. Since these two languages are very similar, it is quite easy to convert programs from one to another. I have seen huge number crunching programs in Clean (for instance, programs to model lightning, by Lucian Lima and Lucian Martins) performing better and much faster in Clean than in MatLab with a C toolbox. Since Haskell has not efficient implementation of arrays, it is impossible to port such a program to Haskell. Thus, here is my first complain about Haskell: It does not provide efficient array processing.

    Clean compiler (thanks to unique types) catch most input/output errors; Haskell will catch the errors only at runtime, and I do not like programs from my company crashing at the client’s machine (who does?); for instance, Haskell compiles the program below without a single warning; Clean issues an error message, and fails to compile.

    module Main
    where

    import IO

    main = do fromHandle <- getAndOpenFile “Copy from: ” ReadMode
    toHandle <- getAndOpenFile “Copy to: ” WriteMode
    contents IOMode -> IO Handle

    getAndOpenFile prompt mode =
    do putStr prompt
    name do putStrLn (“Cannot open “++ name ++ “\n”)
    getAndOpenFile prompt mode)

  16. haskell programming / Jul 29 2008 7:50 pm

    > 24. It (really) has no pointers.

    what about Foreign.Ptr then there’s Foreign.StablePtr and System.Memory.Weak

  17. DiscoNeckTed / Dec 21 2008 12:33 pm

    >> 24. It (really) has no pointers.

    > what about Foreign.Ptr then there’s Foreign.StablePtr and System.Memory.Weak

    What part of “Foreign” you don’t understand?

  18. anon / Jan 7 2009 1:43 am

    Click to access gpugen.pdf

    Python is great, but hard to take advantage of GPU and go
    parallel.
    Any bridge between Python and Haskell?

  19. Yin Wang / Sep 20 2009 8:58 pm

    You pretty much listed all the superficial criteria that a programmer tries to find in a language. So, surely everybody should love Haskell :-) I like Haskell quite a lot, but as a general rule, don’t fall in love anything because love makes you blind and don’t see areas that need improvements. Of course, women are an exception :-)

  20. david / Nov 26 2009 9:20 pm

    “Languages without automatic memory management are simply not candidates for writing serious application level code in the modern world.”

    except for games. i just felt that needed saying.

  21. John F. Miller / May 10 2011 11:34 pm

    36.) This is the only one where I really disagree. Haskell’s strings are just clunky when it comes to normal language patterns. For example assembling an error message from a template a various bits of data inevitably becomes a tangle of “\””++var ++”\”\n”++ etc… I desperately miss heredocs and interpreted strings in Haskell.

Trackbacks

  1. Top Posts « WordPress.com
  2. Why Haskell is beyond ready for Prime Time « Integer Overflow
  3. My Functional Programming Intro « More than a Tweet
  4. Func. Prog. Lang. Ref. « More than a Tweet
  5. 10 programming languages worth checking out | IdeasCart
  6. Functional Programming Concepts for the Lay Programmer – Part 1 | Stephan Sokolow's Blog
  7. My Thoughts On Haskell « Coding code

Leave a reply to Mike Cancel reply