I am comfortable with programming in C and C#, and will explore C++ in the future. I may be interested in exploring functional programming as a different programming paradigm. I am doing this for fun, my job does not involve computer programming, and am somewhat inspired by the use of functional programming, taught fairly early, in computer science courses in college. Lambda calculus is certainly beyond my mathematical abilities, but I think I can handle functional programming.

Which of Haskell or Scheme would serve as a good intro to functional programming? I use emacs as my text editor and would like to be able to configure it more easily in the future which would entail learning Emacs Lisp. My understanding, however, is that Emacs Lisp is fairly different from Scheme and is also more procedural as opposed to functional.

I would likely be using "The Little Schemer" book, which I have already bought, if I pursue Scheme (seems to me a little weird from my limited leafing through it). Or would use the "Learn You a Haskell for Great Good" if I pursue Haskell. I would also watch the Intro to Haskell videos by Dr Erik Meijer on Channel 9.

Any suggestions, feedback or input appreciated.

Thanks.

P.S. BTW I also have access to F# since I have Visual Studio 2010 which I use for C# development, but I don't think that should be my main criteria for selecting a language.

Minor side comment: the lambda calculus is an extraordinarily simple system; the cool thing about it is not that it's complex, but the opposite; that you can express everything you want in such a simple system. Start with a programming language; now throw out EVERYTHING except variable references, function definitions, and function calls. Voila! Lambda calculus.
–
John ClementsApr 18 '11 at 23:05

11 Answers
11

In my personal point of view, the main basis of modern¹ functional programmings are higher-order functions, a static type system, and algebraic datatypes and pattern matching.

Between a Scheme, a ML and a Haskell, I would choose the ML because I think it's the most relevant to this definition. Scheme doesn't have static typing (there is Typed Racket, but it's not for the scheme beginners), and Haskell has too much other stuff (monads, lazy evaluation...) that, while interesting, may divert attention from the important basis.

SML and OCaml are equally interesting; I'm more used to OCaml, and it has a more "practical" feeling that is nice (but if you really want "practical" to the risk of losing your soul, you may as well pick F#).

Scheme and Haskell are also very interesting languages. Scheme emphasis on macros is interesting, but not directly related imho to functional programming (it's another of the things in the world you should definitely try, as well as eg. logic programming, stack-based languages, and capability-oriented E).

Haskell is definitely a great language and, I think, a mandatory point for the aspiring gurus of functional programming. But as the core languages of OCaml and Haskell are very much similar (except for lazy evaluation that, as I said, is imho distracting for the beginner), it's easy to learn Haskell once you know the basics of OCaml. Or rather, you can concentrate on the weird stuff, and you don't have to assimilate the basics at the same time.
Similarly, once you have seen OCaml, and possibly also Haskell, and still want to learn more, you should look at Coq or Agda. Yet few would recommend Coq or Agda for a first introduction to functional programming...

To make my point clear : I think that learning OCaml (or SML) then Haskell will make you as good a functional programmer as learning Haskell directly, but more easily (or less painfully).
Besides, OCaml and Haskell both have good things differentiating them, and it's interesting to know about the advanced features of both. Just learning Haskell is poorer in that aspect (though of course you could learn OCaml after Haskell; I think it's less logical and will get you more frustrated).

¹this definition is controversial. Some Scheme folks will claim static typing has nothing to do with functional programming. Some Haskell people will claim that their definition of purity ("what Haskell does, but no more") is a sine qua non condition for being a functional language. I agree to disagree.

Thanks for nudging me towards OCaml, and yes I will risk my soul and explore F#. I do develop for Linux, Mac OS X and Windows (mainly the former) but FSI does appear to be available for all three platforms (running mono on Linux and Mac OS X) which I already do. The fact that the full weight of Microsoft is behind a functional programming language (albeit an "impure" one), should be welcomed rather than decried by fans of functional programming.
–
hazizApr 22 '11 at 14:34

+1 for ML; it is more clear than Haskell.
–
m3th0dmanAug 26 '12 at 15:49

I also find it a good idea learning SML or OCaml, then Haskell (+1). After knowing these languages, picking up another one (e.g. Scala) is very easy. Additionally one could look at Scheme, Common Lisp and Clojure (in this order), to have a feeling of the dynamic languages.
–
GiorgioJul 27 '13 at 10:39

@haziz: Even when they create good software, Microsoft (or, for that matter, Oracle, etc) remains a monopolist, with all the involved bad practices like customer lock-in, incompatible formats, incompatible implementations, etc.
–
GiorgioJul 27 '13 at 10:41

If you're interested in the more advanced concepts in functional programming, then go with Haskell. There's a proper type system and a strict prohibition against mutation. Still, Haskell is not for the faint-of-heart.

If you just want an introduction to functional design, go with Scheme. The syntax is much easier to learn and read. It does allow procedural programming, but just discipline yourself not to use any procedure with a ! at the end of the name.

My two cents with respect to functional programming is to not get hung up on a particular language, but learn the key concepts of functional programming. I learned functional programming by being tossed headfirst into a project in which my boss insisted all development be done in APL. APL is a functional array processing language and is as far away from LISP, Haskell, or any other mainstream programming language as you can get. The real payoff was when I found that once I "grokked" the functional programming paradigm and mentally learned how to auto-magically decompose a problem into a functional program, I was really no longer intimidated by the idiomatic aspects of other functional languages like Haskell, OCaml, Scheme, Scala, and Clojure. I've since had quite a bit of success in coming up to speed with other functional languages and have written pretty good commercial quality code in OCaml, Scala, and SBCL.

If I were to choose a first functional language, I'd probably choose Haskell or Steel Bank Common Lisp (SBCL). For Haskell, I'd read Learn You a Haskell..., Real World Haskell, The Haskell Road to Logic, Maths and Programming, and Pearls of Functional Algorithm Design. For CL, I'd read Land of Lisp, Paradigms of Artificial Intelligence Programming, and (if you're really hardcore) Let over Lambda. You can mix and match all those books to get a broad overview of practical functional programming approaches and concepts.

I'd also consider learning Clojure and Scala, as they are both very good and very expressive functional languages in their own right (despite what FP purist might say).

The correct answer is, of course, both! So it's just a question of which language to tackle first. My situation is identical to yours. I really enjoyed The Little Schemer immensely. You will definitely understand the basic constructs of functional programming after getting through that (and have a place to put your jelly stains!)

I'm about a quarter into Learn You a Haskell for Great good. I'm enjoying that quite a bit as well, but the two books couldn't be more different. Learn You a Haskell has a very traditional approach to teaching a specific language. The Little Schemer is specific to Scheme, obviously, but is much more concerned with teaching the fundamentals of functional programming, not the language of Scheme.

I definitely recommend starting with The Little Schemer. It's less practical, but more fundamental.

Is there any reason why ML isn't one of your options? There is a fair amount of introductory material available including books and course handouts. If you like The Little Schemer you might also enjoy The Little MLer. Finally, you can easily make the transition to F# later. (Not that I am knocking Haskell or Scheme - ideally learn all three).

Also, a word of warning about Emacs Lisp. I don't think either Haskell or ML will prepare you for it. A Lispy language like Scheme will help but there are still major differences eg. dynamically scoped variables. Emacs extensions, by their very nature, tend to be more imperative than functional - they are all about altering the state of the editor.

Thanks for nudging me towards ML/OCaml, and yes I will "risk my soul" and explore F#. I do develop for Linux, Mac OS X and Windows (mainly the former) but FSI does appear to be available for all three platforms (running mono on Linux and Mac OS X) which I already do. The fact that the full weight of Microsoft is behind a functional programming language (albeit an "impure" one), should be welcomed rather than decried by fans of functional programming.
–
hazizApr 22 '11 at 14:37

BTW I did order The Little MLer from Amazon and have already received it and started on my Journey. I also just added Learning F# to my library. Seems to be a more mainstream teaching guide, that I will be using to supplement The Little MLer with.
–
hazizApr 22 '11 at 14:42

I really recommend this. You will learn Haskell using a real and interesting problem, and you will learn the best lesson of scheme from playing with the interpreter you build. If you go this route, keep a few good Haskell introductions around. You will understand them better if you have a problem to solve.

I actually used this wiki/pdf to learn Haskell and brush up on my OCaml skills (by translating idiomatic Haskell to OCaml). It would be pretty cool if someone could take this material and "fork" it for several functional languages. Could be the basis for a pretty cool functional language shootout!
–
MarcApr 19 '11 at 18:39

1

The main problem with this is that it introduces parsec without introducing monads.
–
alternativeApr 19 '11 at 23:17

@alternative parsec has a Monadic interface, but it also has an Applicative interface, not to mention numerous other functions. It isn't that unreasonable to introduce Parsec before the monadic generalization
–
Philip JFAug 27 '12 at 2:34

I would go with Haskell. In scheme, you may be pushed to do procedural stuff, and its type system isn't nearly as helpful has Haskell's, which is great for a beginner as it pretty much checks that your code is correct at compile time.

"pretty much checks that your code is correct" is very wrong. No type system can do that. (Unless your type system is a real theorem prover.)
–
Eli BarzilayApr 19 '11 at 2:59

3

@Eli, have you used Haskell? While theoretically this statement is obviously false, in practice I find it to be pretty accurate, at least in comparison to every other language I have used. That said, I actually disagree that this is a good property for a beginner. When I am learning the ropes, I would rather see specifically what my code did wrong, rather than having the compiler yell at me that it's wrong and having to fight with it when I don't even know the vocabulary the error messages are using.
–
luquiApr 19 '11 at 3:24

1

@Eli "pretty much" is the key term here. In Haskell you spend more time thinking about how to implement it, then the implementation comes pretty easily. Then you typecheck it to make sure your maps, folds, etc, are sane.
–
alternativeApr 19 '11 at 12:43

@Eli Barzilay: Haskell's type system sure seems like it's very close to being a theorem prover. It certainly created an environment where theorem provers almost seem more common than other tools. (Not that I'm implying a causal relationship.)
–
greyfadeApr 19 '11 at 22:24

@luqui -- Yes, I used it; no, it's still a false statement, both in practica and in theory. That's not something that is unique to Haskell though.
–
Eli BarzilayApr 19 '11 at 23:06

I agree with the "learn both" point, but there's a few more points that weren't mentioned so far. First of all, if you're new to functional programming and you go with Haskell, then you need to face several new things besides FP: you need to learn how to live in a lazy environment which can take a considerable effort, and you need to deal with a "real" type system which can be very far from what you use in C or C#.

Scheme, OTOH, does have a foreign looking syntax, but there is no static type system to learn, and it's a strict language so things are more familiar. In addition, Scheme implementations tend to be very malleable -- for example, Racket takes that to an extreme and provides a lazy variant and a statically typed one. This means that you can start with the "easy" stuff and get the hang of using a functional language, and later on you can grow yourself and use the typed variant and the lazy one. They should be easier now, since you get to deal with one feature at a time. To be clear, the concepts are going to be new enough that the syntactic issue is going to be minor and mostly irrelevant. In other words, once you start getting to the new concepts, you'll be busy enough that the syntax will just disappear. (And if you really care about syntax, then Haskell's syntax is something that I personally consider very elegant -- but that's because it's also very far from your average C/C#/C++ syntax.)

But having said all of that, I think that there's also a good point for F# -- you say that you do this as a side thing, but when you learn FP you will soon want to use all of that good stuff. Using F# means that you can do more "real" things since it's probably easy to tackle the same kind of problems that you deal with in your day job. Ideally, you'll get to a point where you'd see the advantage of using that over, say, C# -- and use it in some project. So while you're right in not choosing F# only because it's easier for you to access, you should consider it since there's nothing better than actually using these new concepts. In contrast, if you use Scheme or Haskell and consider it a toy language for your purpose (even if you know that some people use it for real applications), then you'll never take the whole FP thing too seriously. [But YMMV, it's mostly based on subjective observations and can vary greatly from one person to another.]

In one of the answers you received to your question, I found this link quite interesting, because it gives you a a taste of Haskell and Scheme.

In addition to that nifty link, here is my take on your question.

If you're coming from an imperative programming background, you may wind up putting a lot of effort into learning functional programming. I would make sure that learning experience is not empty. That is that you can apply it to your current or next job or that it will help you in some other way.

There are a lot of good languages out there. The Scala people would extol their language, as would the Clojure and CL folks. Even Pythonistas claim laziness. Other people who answered you suggested ML. Amit Rathore who wrote Clojure in Action might even suggest you learn Haskell.

You mentioned Windows and F#. Will that help you in your current position? I don't know anything about F#. Is it functional enough? I ask that, because IMHO Python has functional constructs, but it's not like programming in Clojure.

To summarize, learn a functional language that is "really" functional and in doing so makes best sense for your situation.

I think it's easy to get caught up in debates about languages, and miss the point. For someone who just wants to learn what FP is about, the differences between Ocaml/ML/Scheme/Haskell aren't half as important as your comfort with the material (books, videos, tools) you use to learn it. And whether or not you have a friend to help you learn to certain language trumps everything else.