Good Functional Language for a Noob?
September 17, 2012 10:02 PM   Subscribe

I'm looking for a solid language to work with for learning functional programming. I think Python piqued my curiosity, as has working with ANTLR and trying to get a handle on that beast of a program... Understanding syntax trees and seeing how LISP expressions are like trees... It's all fascinating to me. What's the best language for a functional newbie?

CAR/CDR is confusing to me and the damned parens is intimidating even though I'm utterly fascinated by it all... Haskell, I know is pretty strongly functional, and I know Scala is a hybrid... And of course Scheme. Is Scheme or CLISP better for beginners (or is it really irrelevant?)

I'm on a WinXP machine so I'd like to know what the best environment for running your suggested language is, as well...

Why am I not just rushing into LISP/Scheme/Racket? Aforementioned Parens and CAR/CDR terminology. The syntax of those languages intrigue me, otherwise.

What does Haskell have to offer that they don't? It seems to be more like imperative languages when I read it, so is that easier to dig into? I see that there's Learn You a Haskell Real Good (and now, Learn you an Erlang Real Good -- not that Erlang is necessarily a language I want to learn about, but I believe that's also functional?)

I'm sorry I'm so vague, but I'm so curious. I don't even know what, exactly, I can do with these languages, but they seem so powerful and expressive and they seem to be beckoning me towards them. HALP!
posted by symbioid to Computers & Internet (21 answers total) 7 users marked this as a favorite
I'm not a functional enthusiast, but I found this interesting recently (arguing for clojure):
posted by primethyme at 10:08 PM on September 17, 2012

There's a Coursera course Functional Programming Principles in Scala starting today, you might care.
posted by themel at 10:37 PM on September 17, 2012 [1 favorite]

Scheme is preferable to CLISP because the latter is a bit of sprawling mess, while Scheme was very much built to be a smaller, simpler, more principled implementation.

But there's also Erlang, which is functional and designed in a modern fashion for concurrency, so it's a good choice for something up to date as well as functional. The Joe Armstrong book is the gold standard.
posted by fatbird at 10:52 PM on September 17, 2012

This explains in a very balanced way why Erlang is popular for building scalable infrastructural software: a key part of GitHub, CouchDB (and thus a chunk of Chef), Call of Duty's servers, Riak, RabbitMQ, etc.

You'll do concurrent programming in Erlang before you even leave the tutorial and, incidentally, learn functional programming just because that's what it requires.

Two birds with one stone, IMO.
posted by Monsieur Caution at 10:55 PM on September 17, 2012

I love Haskell. Major caveat is that I come from a math background, so I kind of dig the theory, as opposed to treating it as a hurdle.

I'm also turned off by LISP/Scheme because I don't like the syntax. There's not enough of it! Haskell lets you write closer to infix style. I like

2 * x + y

much more than

(+ (* 2 x) y),

although Haskell can end up looking like

main = do return $ show $ f1 <> (Just 1) <> (Just 2)

That said, LISP lets you get closer to the metal, and you won't get anything like the experience of manipulating ASTs in Haskell. (Some might say that Haskell's higher-order functions mean you don't have to.) Haskell comes from theorists looking for ways to communicate new concepts in computation, so there is always the risk of Logic or Category Theory popping up.

If you want more more Haskell advocacy just ask. If you want to dip your toes, borrow a copy of O'Reilly's "Real World Haskell". I actually bought the dead tree version, and it's what helped me get a serious start. (Though it seems like it's a book that everyone outgrows at some point.)

I'm on Win7, and I use GHC, running under Cygwin and using my favorite text editor. I don't know how that will hold up if I graduate to large projects.
posted by benito.strauss at 11:43 PM on September 17, 2012

You could learn a lot just messing around in the Light Table clojure playground.
posted by Phssthpok at 1:59 AM on September 18, 2012 [1 favorite]

You mentioned one of the canonical answers to this question, Learn You a Haskell for Great Good. The others are Structure and Interpretation of Computer Programs, a famous Scheme course at MIT that's available free online; and the book The Little Schemer.

In my functional programming dabblings, I've found many languages either much too pure to feel practical (Scheme, Haskell) or too adulterated to be interesting (Scala, Emacs Lisp). The ones in the middle, like Standard ML, Ocaml and Erlang might just hit the sweet spot, but YMMV.
posted by vasi at 2:21 AM on September 18, 2012 [2 favorites]

Haskell is about my favorite language, so I'm gonna go ahead and recommend that. It's got more type safety than C and friends, (mostly) provably pure functions, and enough beautiful weird perfect abstractions to keep you busy for a long time.

That said, LISP lets you get closer to the metal, and you won't get anything like the experience of manipulating ASTs in Haskell.

I disagree with this completely. Haskell's type system is really powerful and intuitive. Here's a definition for linked lists, for example:

data List a = Nil | Cons { car :: a, cdr :: List a }

And here's a rose tree:

data Tree a = Tree { leaf :: a, branches :: [Tree a] }

Learn You a Haskell is one of the best programming books I've read period. If you're into irc, #haskell on is widely regarded as beginner-friendly (and is one of the strongest assets Haskell has, IMO), though we might spout too many long words at you. I'm "startling" there. The Haskell wiki is a wealth of information, including things like 99 problems in haskell to get you started and the Typeclassopedia. I also liked A Gentle Introduction to Haskell (though it can be kind of terse) and this How to Learn Haskell page.

It seems to be more like imperative languages when I read it, so is that easier to dig into?

No, Haskell isn't very imperative at all.
posted by wayland at 3:31 AM on September 18, 2012 [2 favorites]

If you want to use macros, Common Lisp is the way to go. There is just no other language that has as powerful a macro system, that uses it as extensively, and that has as large a codebase to search for examples. Read ANSI Common Lisp and On Lisp by Paul Graham and Practical Common Lisp by Peter Siebel.

If you want purity, Haskell is the only game in town. Read what wayland suggests, plus Learn You a Haskell for Great Good! and Real World Haskell. Use Hoogle for reference.

If you want a small language designed for teaching, and a book designed for teaching computer science instead of any particular language, use PLT Scheme (now called Racket) and Structure and Interpretation of Computer Programs.

If you want static types, some kind of macros, and occasionally need impurity, then use OCaml. Read "Introduction to Objective Caml" by Jason Hickey (PDF) and the official INRIA manual.

I really can't think of a good reason to use Emacs Lisp, Python, or SML, because you should just never use Emacs Lisp unless you're extending Emacs, and you should just never use Python for functional programming (I say this as someone who tried to teach a course on functional programming in Python), and if you're going to use SML you should use OCaml instead.
posted by d. z. wang at 8:24 AM on September 18, 2012 [3 favorites]

No, Haskell isn't very imperative at all. (wayland)

In case OP doesn't have the background to infer the sarcasm here, the joke is that Haskell is about as far from imperative as a language can get while still being compiled down to assembly.
posted by d. z. wang at 8:27 AM on September 18, 2012

FYI, there are synonyms for CAR and CDR in Common Lisp if you find the names confusing: FIRST and REST (though there are no synonyms for the chained versions, CDDDR, CADDR, etc. but you should probably use those rarely).

Also note that the term CLISP is not generally used as shorthand for "Common Lisp" (the ANSI standard Lisp), it is the name of one specific implementation of Common Lisp.
posted by jjwiseman at 9:08 AM on September 18, 2012

Well thanks for all the feedback - I'll definitely take more :)

In the meantime, yes, the CAR stuff is really intimidating, and I'm glad they have First and Rest (and some other ordinals), but I'm glad that the chained CADR and all that crazy stuff is recommended to rarely be used.

And one cool thing that helped me understand prefix notation was ANTLR and understanding how it builds an AST and displayed it using parens notation, where the "root" is the first symbol and the branches are the next ones... I don't know if that's coincidence in the way Terence Parr made ANTLR or if that's a standard view of things, but it really made me get a little more of LISPy syntax...

But really seeing later as I looked into it, that really, + and - and all the operators are really kinda like functions so if you treat them as functions, you put them first (mostly in a way that + would be like add 5 2...) I don't know if I can easily grok prefixed/polish, but it makes much more sense to me now.

OK, so that's that. I just - when I look at functional languages, there's so much there that just makes sense (my main problem is... I'm not a particularly mathy kind of guy, so I'm worried I may have issues really grokking the details). But I want to try, because... It just seems so elegant!
posted by symbioid at 11:15 AM on September 18, 2012

I am a researcher in programming languages, so I do a fair bit of functional programming.

Others have not yet suggested Coq, which is a proof assistant in wide use, developed by the same people who developed OCaml. Coq is a programming language which makes explicit the Curry-Howard correspondence, which, without going into any formalism, says essentially that proofs are programs are proofs. Where Haskell claims to be inspired by this result, Coq makes it explicit. That is, every well-typed program in Coq is in fact, a valid proof of some theorem. Benjamin C. Pierce's book Software Foundations is free and a wonderful introduction to both functional programming and Coq. One caveat: Coq is not Turing-complete as the vast majority of programming languages are, but this ends up not being a problem. I will be very honest in stating that I really wish that I had learned Coq before any other functional language. You won't be doing very much programming of "real programs" in Coq, but as far as learning about functional programming goes, I don't believe it gets any better than Coq.

If you feel you must apply your learnings immediately to real-world applications, read on.

In my lab, we use Scala, and to be honest, Scala has ruined me for languages like Haskell or OCaml. That is to say, I just far prefer writing it. It's got many of the features of these other languages, such as pattern matching, nice monad support, etc. but the syntax is (relatively) familiar and you can call Java from Scala trivially, which ends up being quite nice. In my opinion, Scala can allow you to more closely link ideas in functional programming to the imperative mode of thought with which it sounds like you are already familiar. I prototype things in Scala now even more frequently than I prototype them in Java, because writing Scala is so easy, and you can do imperative things just as easily as you can do functional things, if you must.

The problem with Scala, though, is that it is a bit harder to dig in to the explicitly functional side of Scala, because there are lots of people using Scala for a lot of different reasons, and have different levels of understanding regarding functional programming.

If it ends up that Scala isn't your cup of tea, I would recommend either Haskell or Scheme (specifically, the Racket dialect), in both cases because of the depth of resources available for learners. Haskell has Miran Lipovańća's fantastic free book (Learn You A Haskell) which others have recommended. I have even used this book as a reference for functional ideas when programming Scala. Scheme has, of course, the classic text Structure and Interpretation of Computer Programs also available online for no money, as well as How to Design Programs, which is a bit lighter and easier to read. Scheme's main disadvantage in this circumstance, I think, would be that Scheme is a bit hard on the eyes (to read), but it's worth training your mind to grok Scheme source code since S-Expressions are so widely useful even outside of Scheme, as a format for data transfer and storage.

I think that Common Lisp would not be worth pursuing right now, since, while powerful, it is a bit unfriendly compared to the above listed languages, without much tangible benefit. People will argue, but you have to start somewhere, and I don't believe that CLisp is the place to do that.
posted by eak at 12:57 PM on September 18, 2012 [1 favorite]

Holy language nerdery, batman! Another book, fairly advanced: Programming Languages: Application and Interpretation; uses Scheme, mostly. Also of note, HtDP which eak linked to systematically uses first and rest, so no car/cadr/caddddrrr nonsense.

Another language, very obscure: Oz. There's a very well-regarded book that uses it, Concepts, Techniques and Models of Computer Programming. It has a very unique approach, but it starts with a model (which the authors call "declarative") that's basically functional programming. One notable particularity of the book is that concurrency (threads) is added before mutable state. The chapter on object-oriented programming also has a very nice treatment of the object/closure duality.

Another language in a similar vein (Gert Smolka worked on both) is Alice ML, which is based on SML. Gert Smolka has also written an introduction to programming using SML, but, erm, it's in German.
posted by Monday, stony Monday at 3:33 PM on September 18, 2012 [1 favorite]

It might also be helpful to brush up on your discrete math/logic skills, since functional programming has a strong mathematical component. I should do that myself. Maybe others could suggest some books... please.
posted by Monday, stony Monday at 3:37 PM on September 18, 2012

Monday, I was just going to come in and recommend DrRacket based on my experiences with Shriram.

Seriously, it's the way to go - compared to other functional languages, it's neither tied down by history (CLISP) nor made obscure by theoretical purity (Haskell). Scheme was made to be small, Racket was made to be good for teaching, and it's still a serious language - hell, Hacker News runs on it. The environment will also run flawlessly and be easy to set up on Windows. Unlike Scala there's no weird build system baggage/cult either.
posted by 23 at 6:38 PM on September 18, 2012

not that Erlang is necessarily a language I want to learn about, but I believe that's also functional?) (symbioid)

Erlang is neat because it offers a different model of concurrency. If you're done concurrency in imperative languages, you're using shared-state concurrency. Erlang uses message-passing concurrency, which makes it impossible to commit a whole class of errors based on unexpected interleaving of mutations. Imagine if every function in your program were wrapped in an MPI interface, but the result weren't horrifying to contemplate.

I don't even know what, exactly, I can do with these languages, (symbioid)

Franz, Inc. maintains a list of Lisp success stories. The sidebar at the left divides them by field. There are a lot of fields.
posted by d. z. wang at 10:34 PM on September 18, 2012

ek, as long as you seem to know about Coq, what do you think of the pedagogical value of Agda and Qi as first functional languages? My feeling is that the type system is unnecessarily powerful, to the point of being a barrier, but I felt that way about Coq as well and you clearly disagree with me there.
posted by d. z. wang at 10:35 PM on September 18, 2012

OK, another question for you guys -- I had already downloaded Racket but didn't install it when I posted this, and so last night I installed it.

Since Racket is evolved from Scheme and SICP is written for Scheme can I easily use SICP w/Racket? I imagine there's not a lot of issue with function names, but maybe some differences that are fairly easy to look up/convert... Just a little more work than using a more "proper" version of Scheme. (I would think that Racket is still fairly substantially Scheme even though it no longer calls itself such).
posted by symbioid at 7:15 AM on September 19, 2012

DrRacket comes with an option to use the R5RS standard, which MIT Scheme itself mostly supports. Should be under the Language -> Choose language. I've just started out myself (for the second time, hehe) and the only hiccup I've discovered so far is that since the sqrt function is already defined in R5RS, DrRacket will give you an error 'define-values: cannot change constant variable: sqrt'. You'll have to use a different name for implementing the square root algorithm in section 1.1.7 or uncheck the "Disallow redefinition of initial bindings" option in the details section of the Choose Language menu.
posted by Mister Cheese at 8:42 AM on September 19, 2012 [1 favorite]

Racket/Scheme is good fun, but I would also make sure to try statically typed functional programming in some ML dialect as a complement: Haskell (or Coq/Agda/Epigram) is at the Curry-Howard extreme of FP, where your best friend is the type-checker. Type inference in your IDE is a godsend for such languages.
Later (or if skipping Haskell), write some JVM/.NET applications in Scala or F#, just to get a feel for how to integrate functional programs with large APIs.
posted by froghopper at 1:55 PM on September 19, 2012

« Older thywhat?   |   Special Snowflake needs an Alarm Clock! Newer »
This thread is closed to new comments.