Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-03-08T12:54:22.867Z
Answers.Text: To this answer I would add that Haskell is simply easier to read and strongly typed, both things that I find helpful for beginners.
Answers.UserDisplayName: Gorchestopher H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-04T00:30:42.233Z
Answers.Text: 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.
Answers.UserDisplayName: Shriram Krishnamurthi
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-04T00:32:54.450Z
Answers.Text: 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.
Answers.UserDisplayName: Shriram Krishnamurthi
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T05:41:23.737Z
Answers.Text: 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.
Answers.UserDisplayName: Ben I.
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T08:36:31.457Z
Answers.Text: 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)
Answers.UserDisplayName: Miles
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T05:38:51.560Z
Answers.LastActivityDate: 2017-05-24T05:38:51.560Z
Answers.UserDisplayName: Miles
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-04T00:40:24.990Z
Answers.LastActivityDate: 2017-06-04T00:40:24.990Z
Answers.UserDisplayName: Shriram Krishnamurthi
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T10:31:52.730Z
Answers.Text: 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 :)
Answers.UserDisplayName: Ben I.
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T17:26:47.410Z
Answers.Text: @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.
Answers.UserDisplayName: xuq01
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T21:09:38.647Z
Answers.Text: 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/
Answers.UserDisplayName: Peter
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-24T07:29:31.637Z
Answers.LastActivityDate: 2017-05-25T01:08:45.297Z
Answers.LastEditDate: 2017-05-25T01:08:45.297Z
Answers.UserDisplayName: xuq01
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-30T18:10:45.667Z
Answers.Text: 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...
Answers.UserDisplayName: Scott Rowe
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-31T11:59:19.997Z
Answers.Text: 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.
Answers.UserDisplayName: Scott Rowe
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-02-01T03:31:03.947Z
Answers.Text: For FP, abstraction is not a positive. [See](https://cseducators.stackexchange.com/a/7262/8837)
Answers.UserDisplayName: Rushi
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-30T06:30:50.127Z
Answers.LastActivityDate: 2022-01-31T09:12:22.977Z
Answers.LastEditDate: 2022-01-31T09:12:22.977Z
Answers.UserDisplayName: Rushi
Body: <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>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-05-24T04:07:44.200Z
Comments.Text: 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.
Comments.UserDisplayName: Ben I.
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-05-24T05:36:02.223Z
Comments.Text: 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.
Comments.UserDisplayName: Peter
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-01-30T16:27:34.403Z
Comments.Text: My answer below composed from bits and pieces written at different times
  Depending on interest can refactor as appropriate
Comments.UserDisplayName: Rushi
Tags: <functional-programming><language-choice>
Title: Scheme vs Haskell for introducing functional programming
ThreadText: # 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](https://plato.stanford.edu/entries/language-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](https://en.wikipedia.org/wiki/Cognitive_dimensions_of_notations). 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:
  
  1. Have low bar on use : Python
  2. Have clean type inference : ML
  3. Be conceptually simple : Scheme
  4. Have rich expressions : APL
  5. Have a mathematical (aka equational) feel : Haskell
  
  [username_7 username_7](https://cseducators.stackexchange.com/questions/7226/driven-to-abstraction) (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](https://en.wikipedia.org/wiki/Greenspun%27s_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
  
  1. 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!
  2. Real world considerations invariably push against academic ones:
     * *Must be under JVM* : Scala, Clojure
     * *Windows/.NET are my world* : F#
  3. You really want to push the FP envelope at its research-edges? Idris, Agda
  4. The main action is at meta level (you are a devotee/disciple of Paul Graham)? Common Lisp
  5. Etc.
  
  There are dozens (maybe hundreds) of other attributes [we could study](https://en.wikipedia.org/wiki/List_of_system_quality_attributes).
  
  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](https://www.reddit.com/r/programming/comments/99izf/joe_armstrong_because_the_problem_with/)
  
  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](https://en.wikipedia.org/wiki/Willy_Wonka_%26_the_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 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](https://twitter.com/headinthebox/status/1251647851077091328) Popular MOOC on FP
  * [Mark Lentczner](https://mail.haskell.org/pipermail/ghc-devs/2015-October/010068.html) resignation from release manager for The Haskell Platform
  * [Simple Haskell](https://www.simplehaskell.org/) A bunch of folks feeling similarly
  * Google for ftp/amp for more nittygritty details about the controversy [eg](http://nattermorphisms.blogspot.com/2015/02/ftp-dangers.html)
  
  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](https://www.youtube.com/watch?v=ZkLE0jrflwQ). Strongly recommended for teaching basic programming via FP.
  A natural first choice for people who regard [Bird&Wadler](https://www.amazon.in/Introduction-Functional-Programming-International-Computing/dp/0134841891) (Ed-1 mind you!) as the best CS book ever See [interview](https://www.youtube.com/watch?v=9SBR_SnrEiI)
  
  ## Gofer
  
  Earliest and smallest language that can claim to be Haskell.
  See Haskell-gofer [error message comparison](https://stackoverflow.com/a/26071288/3700414)
  
  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](http://blog.languager.org/2014/09/pugofer.html) 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](https://www.reddit.com/r/haskell/comments/3ove2e/got_the_welcome_email_from_edx_fp101x_course_hugs/)
  
  ## Helium
  
  Similar goals to pugofer in terms of beginner simplicity. [See](https://hackage.haskell.org/package/helium)
  
  ## 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](https://agraef.github.io/pure-lang/) 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
  
  ```haskell
  qsort []      = []
  qsort (x::xs) = qsort [y | y ∈ xs, x<y] ++ [x] ++ qsort [y | y ∈ xs, x≥y]
  
  ```
  
  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)  
  
  ---
  
  