<p>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 <a href="https://docs.google.com/spreadsheets/d/1TQsv1ykVOTSfkeLc21jsx1-f2LRnV94z3OLWcv6I2OM/edit#gid=1852095133" rel="noreferrer">programming language poll</a> results, although Scheme (as Racket) still has the edge in introductory courses.</p>

<p>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 <a href="http://www.bootstrapworld.org/" rel="noreferrer">Bootstrap World</a>, but they're using <a href="https://code.pyret.org/" rel="noreferrer">Pyret</a> for some courses now.</p>

<p>There are some good Haskell texts around, e.g. Hutton's Programming in Haskell, and Lipovaca's Learn You a Haskell for Great Good! (<a href="http://learnyouahaskell.com/chapters" rel="noreferrer">free online version</a>), but these are introductions to the language rather than introductions to functional programming - it still seems hard to beat <a href="https://mitpress.mit.edu/sicp/" rel="noreferrer">SICP</a>, which is Scheme based. What text are you using at present?</p>

<p>Interestingly, <a href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf" rel="noreferrer">this critique of SICP</a> from 1987 identifies four issues with Scheme, all of which are addressed in Haskell:</p>

<ol>
<li>Pattern-matching.</li>
<li>A syntax close to traditional mathematical notation.</li>
<li>A static type discipline and user-defined types.</li>
<li>Lazy evaluation. </li>
</ol>

CC BY-SA 3.0
2018-03-08T12:54:22.867Z
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
CC BY-SA 3.0
2017-06-04T00:30:42.233Z
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
CC BY-SA 3.0
2017-06-04T00:32:54.450Z
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
CC BY-SA 3.0
2017-05-24T05:41:23.737Z
We're using [The Little Schemer](https://mitpress.mit.edu/books/little-schemer), which is a wonderful little book!  I shall miss it if I switch.
Ben I.
CC BY-SA 3.0
2017-05-24T08:36:31.457Z
See pp 60-61 of [Hello World #2](http://s3-eu-west-1.amazonaws.com/rpi-magazines/issues/full_pdfs/000/000/003/original/HelloWorld02.pdf)
Miles
CC BY-SA 3.0
2017-05-24T05:38:51.560Z
2017-05-24T05:38:51.560Z
Miles
<p>As the kids these days would say, you're doing it wrong.</p>

<p>Let me explain.</p>

<p>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.</p>

<p>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 <code>set!</code> at all. Only near the end of the pedagogic language tower do you find <code>set!</code> (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:</p>

<p><code>&gt; (define x 3)</code></p>

<p><code>&gt; (set! x 5)</code></p>

<p><code>set!: this function is not defined</code></p>

<p>DrRacket is saying "you've put something in the function application position called <code>set!</code> and I don't know what it is" — the same error as if you had written <code>(foo x 5)</code> 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.</p>

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

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

CC BY-SA 3.0
2017-06-04T00:40:24.990Z
2017-06-04T00:40:24.990Z
Shriram Krishnamurthi
<p>Although Scheme does have a <code>set</code> function, you don't need to allow students to use it. Obviously, <code>set</code>, <code>print</code>, <code>begin</code> and loops are all potentially very useful for debugging, but it's OK to tell them that they are not allowed to <code>set</code> other than when debugging. Thus, you don't need to change your language if all you want is to stop students from abusing <code>set</code>, especially if you're doing great with Scheme!</p>

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

<ul>
<li>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.</li>
<li>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 <code>set</code> and <code>begin</code>, tell the students they may not use them at all!</li>
<li>Cleaner type system. No type classes and the like.</li>
<li>Again, SICP and the Little Schemer are really nice; HTDP is also great.</li>
</ul>

<p>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 <code>ref</code>s!</p>

CC BY-SA 3.0
2017-05-24T10:31:52.730Z
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.
CC BY-SA 3.0
2017-05-24T17:26:47.410Z
@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
CC BY-SA 3.0
2017-05-24T21:09:38.647Z
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: http://courses.cs.washington.edu/courses/cse341/17sp/
Peter
CC BY-SA 3.0
2017-05-24T07:29:31.637Z
2017-05-25T01:08:45.297Z
2017-05-25T01:08:45.297Z
xuq01
<p>Below written from pov that functional programming (FP) is the only way to go.
This is of course not literally true. But people of other viewpoints can express their's better than I can. So I'll stay with mine; here goes!</p>
<h1>Constructing the Ideal CS-101 language</h1>
<p>The PL-no-1 becomes willy-nilly the mentalese or <a href="https://plato.stanford.edu/entries/language-thought/" rel="nofollow noreferrer">Language of Thought</a> for the student for their life. Or at least for a long time after. So it behoves us to make good choices here!</p>
<p>Following are the desiderata I consider key and the closest corresponding ideal language.  Here's a <a href="https://en.wikipedia.org/wiki/Cognitive_dimensions_of_notations" rel="nofollow noreferrer">wider set</a>. I invite you to think through your own personal set. Main point being:
<strong>Decide your attributes before your language.</strong></p>
<p>The medium for CS-101 should:</p>
<ol>
<li>Have low bar on use : Python</li>
<li>Have clean type inference : ML</li>
<li>Be conceptually simple : Scheme</li>
<li>Have rich expressions : APL</li>
<li>Have a mathematical (aka equational) feel : Haskell</li>
</ol>
<p><a href="https://cseducators.stackexchange.com/questions/7226/driven-to-abstraction">Scott Rowe</a> (and like-minded) will exclaim: Where in all this is...</p>
<h1>The machine that makes this world possible?!</h1>
<p>Yes machine understanding matters. But postponing that causes less damage than reversing the order to machine-first and have students get into the bad habit of getting hung up on implementation/efficiency questions and neglect semantics.  This is of course the point around which the maximum amount of disagreements and disputes occur. I don't claim to be without bias. I only claim to be on the better side.</p>
<p>My slogan here:</p>
<h1>Semantics before efficiency;</h1>
<h1>Ontology before semantics</h1>
<p>This answer will make sense if that is agreeable.
If its not you probably want to stop reading here!</p>
<p>The first part of the slogan is sufficiently over quoted that I can leave it alone. The second is less known... And more important</p>
<p>When we teach there are two things that interact:</p>
<ul>
<li>the concepts we wish to teach</li>
<li>the key-elements of the PL used</li>
</ul>
<p>Both these are the ontologies though from different domains.
When they gel the flow is smooth: rewarding to teacher, illuminating to student.
When not it becomes like Bernard Shaw's pig metaphor:</p>
<blockquote>
<p>Never wrestle with a pig. You get dirty, and besides, the pig likes it.</p>
</blockquote>
<p>The last may be unverifiable but the rest stands</p>
<p><strong>When the course objectives (teacher ontologies) and the PL's ontologies mismatch everyone suffers</strong></p>
<p>An example: Lists (&quot;singly linked lists&quot;) in C start with:</p>
<pre><code>struct node
{
  T elem;    /* Whatever T may be */
  struct node *next;
};
</code></pre>
<p>Did you notice that there are TWO types there? No?? Let me spell it out</p>
<pre><code>typedef node *nodeptr; 
struct node
{
  T elem;
  nodeptr next;
};
</code></pre>
<p><em>Which of <code>node</code> and <code>nodeptr</code> is the concrete C model for the abstract list type?</em><br />
Now you may consider this a hairsplitting question but it becomes key from the ontology pov. Because from the ontology-pov the abstract list type falls between the two concrete C types <code>node</code> and <code>nodeptr</code>.</p>
<p>In effect then all of C is coding up around the fact that:<br />
<strong>Not only C has no lists; it does not even have user defined lists</strong></p>
<p>[If you disagree with that look at <a href="https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule" rel="nofollow noreferrer">Greenspun's tenth rule</a>]</p>
<p>IOW I discard the machine-first without much compunction.</p>
<p>I also discard the OOP-first philosophy. Justifications for this are for elsewhere...</p>
<h1>Other Desiderata</h1>
<p>But there are other desiderata that are more real. I happen to choose to de-prioritize them. Others may — justifiably — choose otherwise. For example</p>
<ol>
<li>FP is proverbially a good fit for parallel programming. If this matters Erlang will come high on your list. And if high becomes highest — great!</li>
<li>Real world considerations invariably push against academic ones:
<ul>
<li><em>Must be under JVM</em> : Scala, Clojure</li>
<li><em>Windows/.NET are my world</em> : F#</li>
</ul>
</li>
<li>You really want to push the FP envelope at its research-edges? Idris, Agda</li>
<li>The main action is at meta level (you are a devotee/disciple of Paul Graham)? Common Lisp</li>
<li>Etc.</li>
</ol>
<p>There are dozens (maybe hundreds) of other attributes <a href="https://en.wikipedia.org/wiki/List_of_system_quality_attributes" rel="nofollow noreferrer">we could study</a>.</p>
<p>All these have their legitimate provenance. They are just not important enough <strong><strong>for me</strong></strong>… <strong><strong>at the moment</strong></strong>.  [I wouldn't put it past Idris/Agda taking over the mantle of Haskell in 2035]</p>
<blockquote>
<p>Problem with OOP: You wanted a banana. You got a gorilla holding the banana and the entire jungle.<br />
<a href="https://www.reddit.com/r/programming/comments/99izf/joe_armstrong_because_the_problem_with/" rel="nofollow noreferrer">Joe Armstrong</a></p>
</blockquote>
<p>My general suggestion would be towards this: You wanted FP. You chose Haskell.
Did you want the 700lb gorilla?</p>
<p>This is usually taken as the FP-er Armstrong bashing OOP</p>
<p>I am turning it round to and applying it to Haskell!  There's just way way way too too much there. For the sophisticated programmer it could be joyous like slurping around Willy Wonka's <a href="https://en.wikipedia.org/wiki/Willy_Wonka_%26_the_Chocolate_Factory" rel="nofollow noreferrer">chocolate factory</a>.  To the beginner its more like getting drowned.</p>
<h1>Scheme</h1>
<p>The trouble is that scheme really doesnt cut it as an FPL by 2022 standards.</p>
<p>Much of Scott Rowe's continual tirades against scheme come from this: <strong>If they (SICP) were going to introduce assignment on pg 300 and invalidate those earlier 300 pages</strong> why did they waste my time?</p>
<p>The problem — <em>this problem</em> — vanishes in Haskell: You cant do assignment/mutation… pg 3 Or 300 Or 3000. Not possible. Its just not there.</p>
<p>The question is a non-trivial one; viz: How far to push in important desiderata? Informally into the culture? Or all the way formally into the language definition?</p>
<p>At the broader level the view (to me at least) is murky.<br />
At the beginner level its quite clear Haskell gets (<strong>this aspect!</strong>) righter than scheme</p>
<p>So then…</p>
<h1>Haskell → Haskellish</h1>
<p>Haskell is great but Haskell has lost its way into labyrinthine complexity of its legendary type system. See</p>
<ul>
<li><a href="https://twitter.com/headinthebox/status/1251647851077091328" rel="nofollow noreferrer">Erik Meijer</a> Popular MOOC on FP</li>
<li><a href="https://mail.haskell.org/pipermail/ghc-devs/2015-October/010068.html" rel="nofollow noreferrer">Mark Lentczner</a> resignation from release manager for The Haskell Platform</li>
<li><a href="https://www.simplehaskell.org/" rel="nofollow noreferrer">Simple Haskell</a> A bunch of folks feeling similarly</li>
<li>Google for ftp/amp for more nittygritty details about the controversy <a href="http://nattermorphisms.blogspot.com/2015/02/ftp-dangers.html" rel="nofollow noreferrer">eg</a></li>
</ul>
<p>My summary:</p>
<p>As a teacher, I wish to stay Haskell-ISH but not Haskell proper as in current ghc at least for CS-101. [Projects is another matter]</p>
<p>Below I suggest alternatives for those who are convinced that Haskell-style FP is the way to go but not ghc itself (for now)</p>
<h1>Nearest to Haskell</h1>
<h2>Miranda</h2>
<p>The original small super elegant expensive proprietory predecessor of Haskell. Recently <a href="https://www.youtube.com/watch?v=ZkLE0jrflwQ" rel="nofollow noreferrer">open sourced</a>. Strongly recommended for teaching basic programming via FP.
A natural first choice for people who regard <a href="https://www.amazon.in/Introduction-Functional-Programming-International-Computing/dp/0134841891" rel="nofollow noreferrer">Bird&amp;Wadler</a> (Ed-1 mind you!) as the best CS book ever See <a href="https://www.youtube.com/watch?v=9SBR_SnrEiI" rel="nofollow noreferrer">interview</a></p>
<h2>Gofer</h2>
<p>Earliest and smallest language that can claim to be Haskell.
See Haskell-gofer <a href="https://stackoverflow.com/a/26071288/3700414">error message comparison</a></p>
<p>The big thing going for it are the series of preludes that make it possibly to sequentially add complexity as Racket does with its teachpacks.</p>
<h2>Pugofer</h2>
<p>My <a href="http://blog.languager.org/2014/09/pugofer.html" rel="nofollow noreferrer">changes to gofer</a> which I most use.</p>
<p>No this is not a &quot;shameless plug&quot;. Its not documented for public use. Not really usable other than by my students/colleagues.</p>
<h2>Hugs</h2>
<p>Can reasonably be called &quot;gofer 2&quot;; falls between gofer and full (modern) haskell; a very sane choice for people going functional; as Erik Meijer demonstrated a <a href="https://www.reddit.com/r/haskell/comments/3ove2e/got_the_welcome_email_from_edx_fp101x_course_hugs/" rel="nofollow noreferrer">few years ago</a></p>
<h2>Helium</h2>
<p>Similar goals to pugofer in terms of beginner simplicity. <a href="https://hackage.haskell.org/package/helium" rel="nofollow noreferrer">See</a></p>
<h2>Pure</h2>
<p>When we get that the whole business of using FP as a general programming ideology is using math equations as a term reqriting system, an explcit rewriting-oriented language becomes an attractive choice. <a href="https://agraef.github.io/pure-lang/" rel="nofollow noreferrer">Pure</a> is one such.<br />
[No first hand experience]</p>
<h1>Wider Span</h1>
<ul>
<li>Erlang : When concurrency is central</li>
<li>ML family (SML Poly-ML, CAML, OCAML) : the original FPLs. In many ways neater than all the rest.</li>
<li>Stay within the Java world : Clojure, Scala</li>
<li>Stay within the .NET : F#</li>
</ul>
<p>Especially given your:</p>
<blockquote>
<p>I learnt FP using SML decades ago</p>
</blockquote>
<p>ML-family may be the sanest choice. Conversely using current publicity ratings to determine a CS-101 medium is really egregious. For those who don't see this there's no use to this conversation. For those who do, there's no need.  Still it may help to hear a Dijkstra hyperbole:</p>
<blockquote>
<p>Programming should be taught with a language not implemented on campus</p>
</blockquote>
<p>Now you can ignore that, or take it literally. I hear it as Dijkstra giving us teachers the freedom to cock a snook at TIOBE indices!</p>
<h1>In short my recommendation</h1>
<p><strong>For you Ben</strong> take ML family if that makes you most comfortable. At least to start with.<br />
[Others can sift the set nearest Haskell to their taste]</p>
<p>I actually like ML family a great deal. Much more teacher-friendly and fad-unfriendly than the modern crop.</p>
<p>Myself I dont use it because I am addicted to Haskell syntax.
[My ideal FPL would be an ML-semantics carrying a Haskellish syntax. No such exists that I know]
Call me silly but I really want my quick sort to be thusly</p>
<pre class="lang-haskell prettyprint-override"><code>qsort []      = []
qsort (x::xs) = qsort [y | y ∈ xs, x&lt;y] ++ [x] ++ qsort [y | y ∈ xs, x≥y]
</code></pre>
<p><sup>Yeah my emacs is setup so that when I type <code>&lt;-</code> I get <code>∈</code> </sup></p>

CC BY-SA 4.0
2022-01-30T18:10:45.667Z
Interesting post, but I was not intending that students should learn about or even *care* about efficiency by learning a bit about how the machine works at the beginning. It would be just: "*Here is how the CPU runs instructions, **it's not magic**. Any questions? Good...*" Then they have the **Notional Machine** that clears up any possible confusion about variables, assignment and indirection, so those will never give them a problem again. Inoculate them against all these ills the first day. Any questions? Good...
Scott Rowe
CC BY-SA 4.0
2022-01-31T11:59:19.997Z
I'll look at the update and language references. I still just feel that there is something *schizophrenic*, something *reality-denying* about trying to sprout wings and fly away from the fact that a computer is an **electrical machine**. As long as you sneak that in before everything else, and make sure everyone gets it, I'll accept your experience and authority to pile things on top. Without it, your students are "lost in space", in my opinion.
Scott Rowe
CC BY-SA 4.0
2022-02-01T03:31:03.947Z
For FP, abstraction is not a positive. [See](https://cseducators.stackexchange.com/a/7262/8837)
Rushi
CC BY-SA 4.0
2022-01-30T06:30:50.127Z
2022-01-31T09:12:22.977Z
2022-01-31T09:12:22.977Z
Rushi
<p>So, I am not interested in which language is <em>better</em>, 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?</p>

<p>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)?</p>

<p>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 <em>about</em> functional programming, the kids did quite a lot of it.</p>

<p>I used Scheme (DrRacket, to be specific), but over the course of the year, I found that kids were sneaking <code>set</code> 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.</p>

<p>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!) </p>

<p>But, other than not having a <code>set</code> 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.</p>

CC BY-SA 3.0
2017-05-24T04:07:44.200Z
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.
CC BY-SA 3.0
2017-05-24T05:36:02.223Z
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
CC BY-SA 4.0
2022-01-30T16:27:34.403Z
My answer below composed from bits and pieces written at different times
Depending on interest can refactor as appropriate
Rushi
<functional-programming><language-choice>
Scheme vs Haskell for introducing functional programming
# Scheme vs Haskell for introducing functional programming

(Asked by: username_0 on 2017-05-24)

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.

**Tags:** functional-programming, language-choice

> **Comments:**
> **username_0**: 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.  
> **username_1**: 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.  
> **username_2**: My answer below composed from bits and pieces written at different times Depending on interest can refactor as appropriate  

---

## 4 answers

### Answer by username_3 on 2017-05-24. Score: 7

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](https://docs.google.com/spreadsheets/d/1TQsv1ykVOTSfkeLc21jsx1-f2LRnV94z3OLWcv6I2OM/edit#gid=1852095133) 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](http://www.bootstrapworld.org/), but they're using [Pyret](https://code.pyret.org/) 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](http://learnyouahaskell.com/chapters)), but these are introductions to the language rather than introductions to functional programming - it still seems hard to beat [SICP](https://mitpress.mit.edu/sicp/), which is Scheme based. What text are you using at present?

Interestingly, [this critique of SICP](https://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf) 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.

> **Comments:**
> **username_0**: We're using [The Little Schemer](https://mitpress.mit.edu/books/little-schemer), which is a wonderful little book!  I shall miss it if I switch.  
> **username_3**: See pp 60-61 of [Hello World #2](http://s3-eu-west-1.amazonaws.com/rpi-magazines/issues/full_pdfs/000/000/003/original/HelloWorld02.pdf)  
> **username_5**: 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.  
> **username_5**: 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.  
> **username_4**: To this answer I would add that Haskell is simply easier to read and strongly typed, both things that I find helpful for beginners.  

---

### Answer by username_5 on 2017-06-04. Score: 7

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


---

### Answer by username_6 on 2017-05-24. Score: 3

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 `ref`s!

> **Comments:**
> **username_0**: 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 :)  
> **username_6**: @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.  
> **username_1**: 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: http://courses.cs.washington.edu/courses/cse341/17sp/  

---

### Answer by username_2 on 2022-01-30. Score: 3

Below written from pov that functional programming (FP) is the only way to go.
This is of course not literally true. But people of other viewpoints can express their's better than I can. So I'll stay with mine; here goes!
Constructing the Ideal CS-101 language
The PL-no-1 becomes willy-nilly the mentalese or Language of Thought for the student for their life. Or at least for a long time after. So it behoves us to make good choices here!
Following are the desiderata I consider key and the closest corresponding ideal language.  Here's a wider set. I invite you to think through your own personal set. Main point being:
Decide your attributes before your language.
The medium for CS-101 should:

Have low bar on use : Python
Have clean type inference : ML
Be conceptually simple : Scheme
Have rich expressions : APL
Have a mathematical (aka equational) feel : Haskell

username_7 (and like-minded) will exclaim: Where in all this is...
The machine that makes this world possible?!
Yes machine understanding matters. But postponing that causes less damage than reversing the order to machine-first and have students get into the bad habit of getting hung up on implementation/efficiency questions and neglect semantics.  This is of course the point around which the maximum amount of disagreements and disputes occur. I don't claim to be without bias. I only claim to be on the better side.
My slogan here:
Semantics before efficiency;
Ontology before semantics
This answer will make sense if that is agreeable.
If its not you probably want to stop reading here!
The first part of the slogan is sufficiently over quoted that I can leave it alone. The second is less known... And more important
When we teach there are two things that interact:

the concepts we wish to teach
the key-elements of the PL used

Both these are the ontologies though from different domains.
When they gel the flow is smooth: rewarding to teacher, illuminating to student.
When not it becomes like Bernard Shaw's pig metaphor:

Never wrestle with a pig. You get dirty, and besides, the pig likes it.

The last may be unverifiable but the rest stands
When the course objectives (teacher ontologies) and the PL's ontologies mismatch everyone suffers
An example: Lists ("singly linked lists") in C start with:
struct node
{
  T elem;    /* Whatever T may be */
  struct node *next;
};

Did you notice that there are TWO types there? No?? Let me spell it out
typedef node *nodeptr; 
struct node
{
  T elem;
  nodeptr next;
};

Which of node and nodeptr is the concrete C model for the abstract list type?
Now you may consider this a hairsplitting question but it becomes key from the ontology pov. Because from the ontology-pov the abstract list type falls between the two concrete C types node and nodeptr.
In effect then all of C is coding up around the fact that:
Not only C has no lists; it does not even have user defined lists
[If you disagree with that look at Greenspun's tenth rule]
IOW I discard the machine-first without much compunction.
I also discard the OOP-first philosophy. Justifications for this are for elsewhere...
Other Desiderata
But there are other desiderata that are more real. I happen to choose to de-prioritize them. Others may — justifiably — choose otherwise. For example

FP is proverbially a good fit for parallel programming. If this matters Erlang will come high on your list. And if high becomes highest — great!
Real world considerations invariably push against academic ones:

Must be under JVM : Scala, Clojure
Windows/.NET are my world : F#


You really want to push the FP envelope at its research-edges? Idris, Agda
The main action is at meta level (you are a devotee/disciple of Paul Graham)? Common Lisp
Etc.

There are dozens (maybe hundreds) of other attributes we could study.
All these have their legitimate provenance. They are just not important enough for me… at the moment.  [I wouldn't put it past Idris/Agda taking over the mantle of Haskell in 2035]

Problem with OOP: You wanted a banana. You got a gorilla holding the banana and the entire jungle.
Joe Armstrong

My general suggestion would be towards this: You wanted FP. You chose Haskell.
Did you want the 700lb gorilla?
This is usually taken as the FP-er Armstrong bashing OOP
I am turning it round to and applying it to Haskell!  There's just way way way too too much there. For the sophisticated programmer it could be joyous like slurping around Willy Wonka's chocolate factory.  To the beginner its more like getting drowned.
Scheme
The trouble is that scheme really doesnt cut it as an FPL by 2022 standards.
Much of username_7's continual tirades against scheme come from this: If they (SICP) were going to introduce assignment on pg 300 and invalidate those earlier 300 pages why did they waste my time?
The problem — this problem — vanishes in Haskell: You cant do assignment/mutation… pg 3 Or 300 Or 3000. Not possible. Its just not there.
The question is a non-trivial one; viz: How far to push in important desiderata? Informally into the culture? Or all the way formally into the language definition?
At the broader level the view (to me at least) is murky.
At the beginner level its quite clear Haskell gets (this aspect!) righter than scheme
So then…
Haskell → Haskellish
Haskell is great but Haskell has lost its way into labyrinthine complexity of its legendary type system. See

Erik Meijer Popular MOOC on FP
Mark Lentczner resignation from release manager for The Haskell Platform
Simple Haskell A bunch of folks feeling similarly
Google for ftp/amp for more nittygritty details about the controversy eg

My summary:
As a teacher, I wish to stay Haskell-ISH but not Haskell proper as in current ghc at least for CS-101. [Projects is another matter]
Below I suggest alternatives for those who are convinced that Haskell-style FP is the way to go but not ghc itself (for now)
Nearest to Haskell
Miranda
The original small super elegant expensive proprietory predecessor of Haskell. Recently open sourced. Strongly recommended for teaching basic programming via FP.
A natural first choice for people who regard Bird&Wadler (Ed-1 mind you!) as the best CS book ever See interview
Gofer
Earliest and smallest language that can claim to be Haskell.
See Haskell-gofer error message comparison
The big thing going for it are the series of preludes that make it possibly to sequentially add complexity as Racket does with its teachpacks.
Pugofer
My changes to gofer which I most use.
No this is not a "shameless plug". Its not documented for public use. Not really usable other than by my students/colleagues.
Hugs
Can reasonably be called "gofer 2"; falls between gofer and full (modern) haskell; a very sane choice for people going functional; as Erik Meijer demonstrated a few years ago
Helium
Similar goals to pugofer in terms of beginner simplicity. See
Pure
When we get that the whole business of using FP as a general programming ideology is using math equations as a term reqriting system, an explcit rewriting-oriented language becomes an attractive choice. Pure is one such.
[No first hand experience]
Wider Span

Erlang : When concurrency is central
ML family (SML Poly-ML, CAML, OCAML) : the original FPLs. In many ways neater than all the rest.
Stay within the Java world : Clojure, Scala
Stay within the .NET : F#

Especially given your:

I learnt FP using SML decades ago

ML-family may be the sanest choice. Conversely using current publicity ratings to determine a CS-101 medium is really egregious. For those who don't see this there's no use to this conversation. For those who do, there's no need.  Still it may help to hear a Dijkstra hyperbole:

Programming should be taught with a language not implemented on campus

Now you can ignore that, or take it literally. I hear it as Dijkstra giving us teachers the freedom to cock a snook at TIOBE indices!
In short my recommendation
For you Ben take ML family if that makes you most comfortable. At least to start with.
[Others can sift the set nearest Haskell to their taste]
I actually like ML family a great deal. Much more teacher-friendly and fad-unfriendly than the modern crop.
Myself I dont use it because I am addicted to Haskell syntax.
[My ideal FPL would be an ML-semantics carrying a Haskellish syntax. No such exists that I know]
Call me silly but I really want my quick sort to be thusly
qsort []      = []
qsort (x::xs) = qsort [y | y ∈ xs, x
Yeah my emacs is setup so that when I type <- I get ∈

> **Comments:**
> **username_7**: Interesting post, but I was not intending that students should learn about or even *care* about efficiency by learning a bit about how the machine works at the beginning. It would be just: "*Here is how the CPU runs instructions, **it's not magic**. Any questions? Good...*" Then they have the **Notional Machine** that clears up any possible confusion about variables, assignment and indirection, so those will never give them a problem again. Inoculate them against all these ills the first day. Any questions? Good...  
> **username_7**: I'll look at the update and language references. I still just feel that there is something *schizophrenic*, something *reality-denying* about trying to sprout wings and fly away from the fact that a computer is an **electrical machine**. As long as you sneak that in before everything else, and make sure everyone gets it, I'll accept your experience and authority to pile things on top. Without it, your students are "lost in space", in my opinion.  
> **username_2**: For FP, abstraction is not a positive. [See](https://cseducators.stackexchange.com/a/7262/8837)  

---

