43 comments

[ 10.9 ms ] story [ 1254 ms ] thread
This seems to be less about Scheme and more about the author wanting to tell a cool story.
That is a true statement for the majority of rants in computer science.
(comment deleted)
> I feel that MIT is risking creating a new generation of idiots by getting rid of Scheme and SICP from their curriculum This is a confused rant about grammar. Scheme isn't the only language with grammar. Students should learn formal grammatical structure in English language class in high school, not programming class in college.
> Students should learn formal grammatical structure in English language class in high school, not programming class in college.

… but they don't. (There are also people—I'm among them—who found discussions of natural-language grammar dull, as belabouring too much a familiar point, until they saw the power that grammatical tools lent in the less familiar setting of formal specifications.)

I think the compsci departments need a new course titled something like "Reading Code" where one learns to read any code fast and efficiently like they would a newspaper article or novel. Now that would be useful.
Can that be taught in a classroom? There are various strategies and tricks one can use, but I think it's better to learn that skill "in the field" than out of a textbook.
It'd be interesting to see a course where you're given a large open-source project (say, Chromium or Linux or Postgres) and your task is to make & submit a small change in the codebase to implement some plain-language user request. The instructor would then walk you through how to download the project, read developer documentation, and build it; how to identify the relevant portion of the codebase, and everything else that your change might affect; how to match coding style & conventions; how to run tests; and how to submit a patch to the maintainers in a way that is likely to get accepted. Reading code is a real skillset, and being able to quickly grok & modify an unfamiliar codebase is a huge leg up in many jobs. Bonus points if the homework assignments for this course are real bug reports, so you end up contributing to open source for class credit.
Universities do have courses that require contributing to an Open Source project. I saw this when working on Servo a couple years ago. I was disappointed in the students. The average university student is not very motivated.

If the course is an elective it's probably better (more motivated students).

One might argue that sounds like software engineering, and that's mostly a separate activity from both programming and from computer science. Of course they overlap.
However, I assert that something like 95% of computer science graduates are actually going to work as software engineers, not as computer scientists. So actually teaching some of that would not be amiss...
I’ve heard of several universities in the UK running this kind of course.
I took a class aimed at teaching us to read scientific papers. Seems like sort of the same situation: lots of “tips and tricks”, but also a skill that needs practice. The class I took essentially brain dumped the tips and tricks part in the first week, then spent the rest of the semester practicing reading papers and pulling insights out of them. The same approach could be used for a class about reading code.
I think "reading code" is actually the easier part of reading code.

The hard parts are (1) understanding the scenarios the code covers, (2) interpreting error messages and edge cases coming from it.

I think that to some extent those things are implied by "reading", just as some level of comprehension is assumed when talking about reading a book.
> I think that to some extent those things are implied by "reading", just as some level of comprehension is assumed when talking about reading a book.

Even better, in fact: one can misread a book with, usually, no reasonable way of determining the extent of one's misreading (see https://news.ycombinator.com/item?id=18380366 for a current front-page example); whereas, when one (mis)reads code, there is always at hand a way to test the accuracy of one's reading (and perhaps find out thereby, in the presence of a sufficiently detailed specification, that the programmer also 'misread' it!).

(comment deleted)
If the code were as well-written as a (readable) novel, it would be reasonable to expect people to be able to read it. Unfortunately, we get asked to read code that's more like Joyce's Finnegan's Wake than Austen's Pride and Prejudice. One does not simply read code like that (or books like that).
(comment deleted)
A cool story no doubt, and this is a blog post, so the author should write whatever they please. But as someone who likes Lisp and genuinely does believe Lisp-family languages have underappreciated and incredibly powerful benefits, I was dismayed to see them leap to the conclusion that it was grappling with s-expressions that allowed him to solve this problem so well. Non sequitur, navel gazey paeans to Lisp are among the reasons why people have so much trouble taking the wild claims Lispers make seriously.
What benefit you think is underappreciated? It's a subjective point of view, but my experience is the contrary: that of Lisp-family languages being hyped to exhaustion.
(comment deleted)
The benefits of macros and code as data is under appreciated. It allows you to remove boilerplate code, and simplify your thought process, which makes for easier to read code. For example, in Clojure you can use macros to make a mini language that converts to HMTL at compile time:

  (defn index []
    (html5
      [:html
       [:head]
       [:body "the index-page"]]))
Or similarly create your route handler on the back end that will serve up your pages:

  (defroutes app-routes 
    (GET "/" [] (index)) 
    (route/resources "/") 
    ; if page is not found 
    (route/not-found "Page not found"))
Note how concise the language becomes, and this code will expand out to all of the necessary opening and closing tags or boiler plate code that makes your code safe and efficient. None of these syntax structures were previously in the language, they are instead created when needed for abstraction.
It seems to me that, if you were to write that in Java, these would just be regular functions returning arrays of Strings or something similar. There would be a similar shortening of the source code. (It still wouldn't be as short, of course, but the same shortening would take place.)

Am I missing something? What's the special macro-ness here that is different from regular functions?

The amount of effort it takes to write a "shortener". Yes, you could do this in java, most likely. However, it would take a ton of effort and likely still not cover as many cases as the easy to write lisp would.

As an example, I have the beginnings of something like that in javascript at http://taeric.github.io/DancingLinks.html (in the appendix. Functions "div, table, etc.") I've done similar in java before to get the same basic structure that I could run in any c like language. I still miss the flexibility of lisp.

edit: to see another example of mine showing some of the advantage of the "macroness" see http://taeric.github.io/CodeAsData.html and see how little code it took to make a tree walker in lisp. (Not just the tree walker, but indeed, the tree.)

One difference is flow control. When you call a function, all the arguments are evaluated before being passed into the function. If you want to delay evaluation, you have to wrap the argument values in a function. When you call a macro, the text forms get passed with no evaluation. Say Clojure forgot to ship with the boolean "or". "or" should evaluate its arguments one at a time (to allow for short circuiting) and return the first non-false value. You could do this with functions, but you have the source-level overhead of manually wrapping everything, and performance overhead of defining and passing an anonymous function for each argument. With a macro, at compile time you just translate the "or" macro into a simpler form that uses "if". This is how Clojure actually implements "or":

    (defmacro or
      "Evaluates exprs one at a time, from left to right. If a form
      returns a logical true value, or returns that value and doesn't
      evaluate any of the other expressions, otherwise it returns the
      value of the last expression. (or) returns nil."
      {:added "1.0"}
      ([] nil)
      ([x] x)
      ([x & next]
          `(let [or# ~x]
             (if or# or# (or ~@next)))))
Also check this http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.h...
Another key point is that most if not all of the replacements are done at compile time, therefore the final code only makes minimal function calls.
> the Scheme programming language, in particular, can help in training non-programmers to think structurally in analyzing expressions in natural language

Well if your making a course for non-programmers maybe.. I should think they would want to do the opposite

It's been over 10 years now. Is there a good post-mortem on the outcome of the switch away from 6.001 and Scheme?
Whatever, MIT dropping lisp looks unbelievably weird.
There are actually more than one reason. I know at least two.

1. The classic Scheme based courses used to bootstrap an OO-DSL embedded in Scheme based on procedures and message-passing (you literally send a symbol by calling the object, which is a lambda, of course with an argument and get back a closure to run - a method). This is an invaluable experience to realize that there is absolutely nothing special about OOP and there is no magic.

2. There are still some gems (which leads to very real a-ha moments!) which cannot be taught in other languages. Here is one:

    (define partially (lambda (f . as)
                        (lambda xs
                          (apply f (append as xs)))))
and then

    (define reverse (partially foldl (flip cons) '()))
TLDR: Perhaps MIT should reinstate Scheme and 6.001, and get rid of Python and the new C1. Somehow I feel that MIT is risking creating a new generation of idiots by getting rid of Scheme and SICP from their curriculum just for the ostensible reason that the recursive style of programming does not reflect the way that programming is actually conducted in industry. Students do not learn programming just to program; learning programming also has important ramifications for the structural thought processes underlying other technical fields, even those that do not seem superficially related (such as patent translation), and it seems that watering down a core programming course for such ostensible reasons undermines the crucial patterns of thinking which are cross-applicable to such other technical fields as well.

I wonder if Richard Stallman would have invented recursive copyleft law if he had never programmed in a lisp/scheme.

I have observed the following in computer science departments.

1. They need students to justify their funding. If students stop taking their courses, they get funding decreases.

2. There are a lot of people that love SICP, and believe it should be the foundation for all computer science curriculum.

3. People pretty much agree it's important for computer science graduates, but the question is, should it be the first course? Are the concepts too hard, too soon? Does it weed too many students out too soon?

4. The industry at large is unconvinced about the benefits of Lisp dialects. They see high productivity gains with Java/C/C++/Python. And many students question why should they learn a language that doesn't advance their careers.

(comment deleted)
In many countries, those that want to learn only industry relevant technologies go to a polytechnic school and not to an university.

Universities are for learning to learn.

I disagree. Most universities have, for example, both a chemistry department and a chemical engineering department. They are different (but related) disciplines, but both belong at the university.

In the same way, I think we need both "computer science" and "software engineering" - but they need to be different departments. They both belong at the university, though. (I'm not sure you go to a polytechnic school to learn chemical engineering.) The problem is, most universities try to teach a computer science degree to people who will work as software engineers (and therefore don't teach them as much software engineering as they should).

During 5 years there is a lot of CS and Software Engineering to learn about.

A solution to that is to have the Engineers college certify which university degrees are actually worthwhile to have engineering as part of their name, and crack down on misuses of the name by people that just had a bootcamp of some sort.

> both a chemistry department and a chemical engineering department. They are different (but related) disciplines

I used to think chemical engineering is about chemistry until I talked to some chemical engineers on the bus I used to commute on. Most of what they study is mechanical engineering, and so, it's better to think of CE as a branch of ME. These people worked in the R&D department of a materials company, so they definitely knew what they were talking about. Their chemistry chops were only marginally better than mine, and I'm an EE.

1. MIT has maybe 5% of funding from tuition. Students are clamoring to go there.

2. True

3. All data seems to suggest showing kids complex problems leads to more learning. "Too hard, too soon" isn't really a rational argument. At MIT it didn't really weed out students either; kids did okay.

4. Nope, nope, and nope. Of those languages, only Python has high productivity. C/C++ is obsolete for anything other than systems programming. The selling point of Java are cheap, interchangeable programmers with a standardized skill set. Small, elite shops do Lisp. But that's not the point. A freshman course isn't designed to be vocational career training, but to give fundamentals. MIT students learned other languages (including Java) in their degree paths as well. This was a freshman course.

> 3. All data seems to suggest showing kids complex problems leads to more learning. "Too hard, too soon" isn't really a rational argument. At MIT it didn't really weed out students either; kids did okay.

Sure it is. When you teach swimming, you don't throw beginning swimmers in the deep end of the pool and tell them, "A challenge is good for you." And in the example I gave of quantum mechanics, even MIT requires previous physics prerequisites.

> 4. Nope, nope, and nope. Of those languages, only Python has high productivity. C/C++ is obsolete for anything other than systems programming. The selling point of Java are cheap, interchangeable programmers with a standardized skill set.

May I refer you to the TIOBE index of programming language usage? [1] The answer is Java, C, C++, and Python in that order, and by a large margin.

[1] https://www.tiobe.com/tiobe-index/

3. We don't throw people in the deep end of the pool, but that has a lot more to do with not wanting people to drown than with what's best for learning. And regarding MIT, it's hardly an example of a school where faculty either know learning science or particularly care.

4. You may refer me, but popularity is quite different from productivity. Most C/C++ is maintaining legacy code. Most Java is either from legacy code, or from environments where productivity isn't a key metric.

I don't say that cynically; productivity is a key metric in startups trying to disrupt the world. In older, slower-moving organizations, a lot of metrics are more important than productivity. If I'm maintaining a system for a bank which handles employee payroll, productivity is likely not even in the top 10 things I'd look for. On the other hand, if an IT employee quits, being able to replace them easily (without assuming a Google-grade interview process or salary) and have someone else be able to take over (without extensive training+documentation processes in place) is really important.