# Scheme vs Haskell for introducing functional programming

So, I am not interested in which language is better, because that is a matter of opinion. What I care about is whether making a switch from Scheme to Haskell will directly help me accomplish my goals. What programming language concepts does each language bring to the fore?

So, I am seeking input from folks who have taught using these languages about the kinds of experiences they had. How did the language features of Haskell or Scheme make your students' experience better (or worse)?

For context, my kids come into their junior year knowing Java, C, and Python pretty well. For their junior year, it was decided that there should be a course in theoretical computer science. In order to have labs, I further decided that we should move away from imperative programming and expose the kids to a functional language. So, while the class was not about functional programming, the kids did quite a lot of it.

I used Scheme (DrRacket, to be specific), but over the course of the year, I found that kids were sneaking set functions into their labs, which ran (to my thinking) counter to the goals of the class. I was also a little displeased with the rather unintuitive way that boolean functions and contracts interacted in the language.

I have, as a result, been thinking about migrating over to Haskell. If I did this, I know that I would need to redesign my labs (and I wonder if the Turing Machines I have them design would suddenly run very slowly!)

But, other than not having a set function, what other benefits might Haskell bring to my students? I don't mind putting in the work to redesign the course if there is a sufficient benefit.

• I see that people are voting to close, but I'm not sure why - are they actually suggesting that there are not pedagogic implications of language choice that are not purely subjective? Surely, Java is a better language to begin teaching Object Oriented Programming than C. Different languages have different features, and these choices have real educational implications. – Ben I. May 24 '17 at 4:07
• This seems like "Good Subjective." I had a similar struggle this year choosing between PHP and Python for a particular unit. Based on the context such a question would certainly have objectivity and research to support one appoach over the other. – Peter May 24 '17 at 5:36

I suspect there'll be more universities switching from Scheme to Haskell for introductory functional programming (FP) courses, mainly for the 'real world' appeal of Haskell. I see 15 mentions of Scheme and 16 of Haskell in the recent SIGCSE programming language poll results, although Scheme (as Racket) still has the edge in introductory courses.

We've a little FP in one of our A-level (secondary school leaving exam) CS courses in the UK, and Haskell seems the popular choice; indeed I'm not aware of any schools using Scheme for this. I know of one school that's been using Haskell with six year olds(!). In the US at school level, Scheme (as WeScheme) features in Bootstrap World, but they're using Pyret for some courses now.

There are some good Haskell texts around, e.g. Hutton's Programming in Haskell, and Lipovaca's Learn You a Haskell for Great Good! (free online version), but these are introductions to the language rather than introductions to functional programming - it still seems hard to beat SICP, which is Scheme based. What text are you using at present?

Interestingly, this critique of SICP from 1987 identifies four issues with Scheme, all of which are addressed in Haskell:

1. Pattern-matching.
2. A syntax close to traditional mathematical notation.
3. A static type discipline and user-defined types.
4. Lazy evaluation.
• We're using The Little Schemer, which is a wonderful little book! I shall miss it if I switch. – Ben I. May 24 '17 at 5:41
• See pp 60-61 of Hello World #2 – Miles May 24 '17 at 8:36
• Just to be clear, Pyret and Racket are not in opposition. We created Pyret because we were tired of having arguments about the virtues of parenthetical syntax and decided to give people a non-parenthetical alternative that is very similar in many ways, though of course having "forked off", we did feel free to make some changes that don't violate the spirit of the Racket tradition. Bootstrap uses both Scheme and Pyret. Bootstrap:Algebra is and will always be in Scheme syntax. The :Reactive, :Physics, and (new) :DataScience curricula are all in Pyret. – Shriram Krishnamurthi Jun 4 '17 at 0:30
• While I have great respect for Wadler's critique, I don't treat it as gospel. It's unsurprising that it aligns with Haskell! In particular, I do not view either static types or laziness as critical, and they can in fact be very problematic too. As for user-defined types, Racket has long since broken with Scheme on that front, as does Pyret (which also has algebraic datatypes). In short, there's a complex design space here. – Shriram Krishnamurthi Jun 4 '17 at 0:32
• To this answer I would add that Haskell is simply easier to read and strongly typed, both things that I find helpful for beginners. – Gorchestopher H Mar 8 '18 at 12:54

As the kids these days would say, you're doing it wrong.

Let me explain.

As I've commented elsewhere, every "full language" has a whole bunch of things that educators would find inconvenient or undesirable. Your Haskell students can use monadic state or UnsafePerformIO too! So Haskell is "just as bad" in principle.

That's why Racket (in an explicit departure from Scheme) gives you the means to define your own languages, and DrRacket ships with several student pedagogic languages already built in. The first few grow in power to the point of being very powerful — but not having set! at all. Only near the end of the pedagogic language tower do you find set! (and its structure mutation variants). Until then, the feature is literally not present. For instance, in BSL (Beginning Student Language), here's a program interaction:

> (define x 3)

> (set! x 5)

set!: this function is not defined

DrRacket is saying "you've put something in the function application position called set! and I don't know what it is" — the same error as if you had written (foo x 5) instead. That is, it's not even saying "sorry, I don't allow you to use state yet"; it's saying "state literally does not exist in my world". Because, at that level, it honestly does not.

So the sense in which you're doing it wrong is that you're using the wrong language level. Your programming environment ships with languages that explicitly preclude the use of state. Instead of using them, you're giving your students the full, unrestricted force of an language in industrial use. It's no surprise that they will find various features in there that you don't want them to. (Sadly, there are no "language levels" for Haskell that can keep students from some of the ugly corners of that language, but the principle applies to every language.)

There are many more trade-offs between using Racket and Haskell, but this one is easily addressed. (Note that I said Racket, because it's Racket's enhancements over Scheme that enable us to create these kinds of language levels. And with very little effort, you could too, if you didn't like the ones we provide.)

Although Scheme does have a set function, you don't need to allow students to use it. Obviously, set, print, begin and loops are all potentially very useful for debugging, but it's OK to tell them that they are not allowed to set other than when debugging. Thus, you don't need to change your language if all you want is to stop students from abusing set, especially if you're doing great with Scheme!

On the other hand, there are a few problems if you choose Haskell over Scheme:

• I/O. Either you have to present it as a "black box" without explaining how it works, or you have to explain monads to them, which could be confusing for FP beginners.
• Stateful programming. Although FP aims to be stateless, oftentimes states are useful in creating real-world programs. Again, to do this in Haskell, you can't get around monads. If students overuse set and begin, tell the students they may not use them at all!
• Cleaner type system. No type classes and the like.
• Again, SICP and the Little Schemer are really nice; HTDP is also great.

Meanwhile, have you considered the ML family? SML and OCaml could be interesting choices too. ML has mutable references, but no mutable variables; but you don't need to tell them about refs!

• TBH, I don't know what monads are. I personally learned FP using SML decades ago, but utilization is so low today... there are many fewer resources around, so I chose to steer clear. As someone who does not consider myself to be 100% solid, I thought that I might really need those resources :) – Ben I. May 24 '17 at 10:31
• @Choirbean You may want to try OCaml then. There are lots of resources (like Real World OCaml, etc) and a quite large community for it. As for SML, it hasn't died, but all available resources (e.g., Ullman) are quite dated. – xuq01 May 24 '17 at 17:26
• In terms of SML, there is a MOOC on Coursera, Programming Languages Part A. I completed the course for my first dive into functional programming and really enjoyed it. The other two parts focus on Racket and Ruby, respectively. There are great videos, lecture notes, exercises, etc. Plus, it taught me Emacs, which I found valuable. Here's a link: courses.cs.washington.edu/courses/cse341/17sp – Peter May 24 '17 at 21:09