Choosing a Functional Language

People often ask me which functional language they should study first. This is my “road map” to functional programming languages.

Clojure is a very nice, highly pure functional language. It’s an untyped Lisp language, which means it emphasizes syntax macros, but it is just a really nicely designed language, very well-suited to data processing and gluing together Java libraries.

Haskell is the flagship typed functional language. Lots of ideas in FP reach their high water mark in this language, which is famous for being difficult to learn and very mind expanding. If you’re interested in terseness and correctness, it’s recommended, but it can require some study before being able to use it in anger.

Factor is, IMO, the to-beat concatenative language. It’s a very different computational model, similar to Forth, where everything is a stack operator, but object-oriented, principled, and has a large and helpful standard library, making it easy to do things like build trivial GUIs and do XML processing.

Prolog is the go-to declarative/logic programming language. Great for learning about non-determinism and doing natural language processing, it has a built-in database and generic parsing framework. The flagship implementation is SWI-Prolog, which has a rich standard library, though the language has a lot of crufty spots due to its age.

J is the open-source array-oriented functional language. In the tradition of APL (which defined its own character set), it is based on the idea of matrix operators and implicit iteration. Its relatives are widely used in finance. The language is basically unreadable to the untrained eye but reaches new levels of terseness.

These represent, IMO, nice “local maxima.” Underneath most of these there are some nice variants that present somewhat different tradeoffs with the same basic flavor.

Under Clojure, you’d find other Lisp variants, namely Racket, Common Lisp (SBCL, Clozure), Scheme (Guile, Chicken), newLisp, and LUSH, which each represent different tradeoffs: Racket is a nice learning environment based on Scheme but with a vast built-in library; Common Lisp is closer to C++ in terms of size, features and pragmatism; Scheme is a tiny academic language with many incompatible implementations, newLisp and LUSH are specific Lisp implementations with small domains (one of which is scientific computing).

Under Haskell, you would mostly find OCaml and Standard ML (SML/NJ, Moscow ML, MLton, Poly/ML), which are smaller and simpler languages. OCaml has a vibrant pragmatic community centered around finance where Standard ML is used almost exclusively in academia. The CLR implementation is called F#, and mostly resembles OCaml; Scala would be the JVM language most similar to Haskell. I personally have a small beef with Scala because I think it is “the worst of both worlds,” both large and complex, hard to comprehend, and by supporting all of Haskell and Java, it winds up being a bit too big and kitchen-sinky. But it has its fans, particularly at RiskSense. Standard ML is more like Scheme: an academic language with a tiny core. It’s famous for its package system though, which only OCaml really does justice to—even Haskell doesn’t have as much power, here, though type classes are pretty convenient. Mythryl is another ML-derived language, a bit closer to C.

Under Factor there is basically Forth, which is still supposedly used by embedded systems (every Forth is different) and Joy, which nobody really knows, an academic exercise that never really went anywhere.

Prolog really only has Logtalk, which is a powerful object-oriented extension, and a few really obscure attempts to modernize it, whose names escape me. Prolog is not widely used, but much more so than any other language in this category (except maybe SQL, if you count that.)

Finally, J has Kx, which is not free, and APL, which is also not free and quite odd (Dyalog being the flagship APL implementation.) But the arguments for the other ones are not especially strong.