38

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.

Walter
  • 16,158
  • 8
  • 58
  • 95
haziz
  • 499
  • 1
  • 6
  • 9
  • 3
    Don't forget `Real World Haskell` – alternative Apr 18 '11 at 23:01
  • 15
    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. –  Apr 18 '11 at 23:05
  • 1
    http://stackoverflow.com/questions/1012573/how-to-learn-haskell –  Apr 18 '11 at 23:14
  • 10
    I can teach you lambda calculus in five minutes. Now, understanding the consequences of what you just learned takes a lifetime. :) –  Apr 18 '11 at 23:38
  • 5
    I chose Haskell over Scheme mainly because it doesn't have so many darned parenthesis! – Joey Adams Apr 19 '11 at 01:09
  • +1 [Matt Might](http://matt.might.net/articles/what-cs-majors-should-know/) recommended using Haskell in his Programming Languages section – Anthony Aug 27 '12 at 00:18
  • Scheme (in particular Racket) is more approachable than Haskell. Racket was designed with the intent of using it to teach. – Mario T. Lanza Aug 14 '14 at 22:06

12 Answers12

31

I would recommend OCaml.

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 to functional programming (it's another of the things in the world you should definitely try, as well as 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 is 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).

For learning OCaml I would recommend Jason Hickey's book draft (PDF).

¹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.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • 3
    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. – haziz Apr 22 '11 at 14:34
  • SML is dead, ocaml exists to write coq – permeakra Aug 21 '12 at 09:35
  • 1
    +1 for ML; it is more clear than Haskell. – Random42 Aug 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. – Giorgio Jul 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. – Giorgio Jul 27 '13 at 10:41
  • I [concur](http://ii.uni.wroc.pl/~lukstafi/FPcourse). – lukstafi Jan 26 '14 at 00:23
26

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.

With Scheme, you can also read the Structure and Interpretation of Computer Programs, which is the best introduction to programming paradigms, hands down. There are lectures on the book from both MIT and Berkeley.

Hoa Long Tam
  • 1,635
  • 10
  • 12
  • 4
    "The syntax is much easier to learn and read" is *very* subjective. –  Apr 19 '11 at 03:20
  • 6
    @luqui: True. Perhaps 'regular' is a better word. No backticks, infixes, precedence, or associativity issues --- just parentheses, lots of infernal, silly parentheses. – Hoa Long Tam Apr 19 '11 at 04:24
17

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.

DaveGauer
  • 1,287
  • 7
  • 12
17

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).

Marc
  • 339
  • 1
  • 8
6

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.]

Eli Barzilay
  • 432
  • 3
  • 7
6

Write yourself a Scheme in 48 hours (in haskell)

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.

Wayne Conrad
  • 1,118
  • 10
  • 20
John F. Miller
  • 236
  • 1
  • 3
  • 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! – Marc Apr 19 '11 at 18:39
  • 1
    The main problem with this is that it introduces parsec without introducing monads. – alternative Apr 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 JF Aug 27 '12 at 02:34
6

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. – haziz Apr 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. – haziz Apr 22 '11 at 14:42
4

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.

alternative
  • 1,542
  • 13
  • 14
  • 3
    "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 Barzilay Apr 19 '11 at 02:59
  • 4
    @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. –  Apr 19 '11 at 03: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. – alternative Apr 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](http://www.haskell.org/haskellwiki/Libraries_and_tools/Theorem_provers) than other tools. (Not that I'm implying a causal relationship.) – greyfade Apr 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 Barzilay Apr 19 '11 at 23:06
  • @mathepic -- when it comes to lgical statements like "correct code", "pretty much" is meaningless. Also, I know very well how you spend your time in Haskell, and believe me -- I know *exactly* the benefits of a type system. As useful at is is, saying that it's checking the code for correctness is plain false. – Eli Barzilay Apr 19 '11 at 23:08
  • @greyfade -- being a type system that is friendly for *implementing* theorem provers is not an accident. HM-style type systems were used in ML, when it was conceived as a language for use in (and implementation of) theorem provers. But I can only repeat what I said -- that doesn't make it any more of a theorem prover. In fact, if you view it as a theorem prover, then the things that it can prove are (in some sense by definition) things that theorem provers can prove automatically -- making it the "boring" parts of proofs. – Eli Barzilay Apr 19 '11 at 23:11
  • @Eli Barzilay How is "pretty much" meaningless? I'm just saying that what would often be a runtime failure in another language tends to be a compile-time failure in Haskell most of the time. – alternative Apr 19 '11 at 23:15
  • @mathepic -- pretty much is meaningless because when it comes to correctness proofs either you do them or you don't. With Haskell's type system, as with other statically typed languages, you get a certain class of guarantees, but that's far from a correctness *proof*. [Obviously, the benefits are there and worth talking about -- some people swear by such static typecheckers, and some say that they catch only the kind of trivial bugs that are easy to catch with a dynamically typed language, with good test suites etc.] – Eli Barzilay Apr 20 '11 at 00:37
  • @Eli Barzilay: I don't think anyone is contending that Haskell's type system is a prover *as such*. We're only saying that it's good enough that the class of bugs it prevents is the vast majority. – greyfade Apr 20 '11 at 01:32
  • @greyfade -- Um... this started with exactly that claim. – Eli Barzilay Apr 20 '11 at 21:00
  • @Eli Barzilay which you translated to us saying that Haskell's type system is a prover. Which we are pointing out is wrong, thus you have been arguing about the wrong subject... – alternative Apr 20 '11 at 22:07
  • @Eli Barzilay: Then perhaps we have a severe miscommunication here. "Pretty much" is a colloquial expression that in this case means something to the effect of "it is not equivalent, but it has an effect akin to." It shouldn't be interpreted as a concrete claim that the type system is a prover *as such*; rather that it is strong enough to *have an effect similar to* a (incomplete) prover. – greyfade Apr 20 '11 at 23:20
  • @mathepic -- yes, "Haskell's type system is a prover" is wrong, which is exactly what I said repeatedly. Going back to your answer, "code is correct" is something that requires a correctness proof, and therefore Haskell's type system does not give you that. Not even in some "pretty much" sense. – Eli Barzilay Apr 21 '11 at 01:50
  • @greyfade -- You're finally getting to the meat of it: I did understand the colloquialism, but for anyone who knows what kind of stuff is involved in proving correctness "pretty much" is very wrong. It's not even "kind of in the same direction". See also what I said in a previous comment: the kind of things that these type system check are facts that are always proved automatically by theorem provers. To make it a bit more technical, in case you know about theorem proving: these proofs are ones that have no computational content. – Eli Barzilay Apr 21 '11 at 01:53
1

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.

autodidakto
  • 281
  • 1
  • 7
0

If it is not pure, you may as well use an imperative language, so Haskell.

isekaijin
  • 508
  • 2
  • 12
0

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.

octopusgrabbus
  • 699
  • 1
  • 8
  • 20
-1

From a relative beginner's point of view, I suggest not starting with SICP if you decide on Scheme, unless your math is quite mature. The book and videos are filled with subtleties and are not at all intuitive to someone starting out.

varreli
  • 11
  • 1