← Back to context

Comment by dswilkerson

3 months ago

I used to be a teaching assistant for CS 61A (intro to programming) at Berkeley teaching from this book with Brian as the instructor.

One of Brian's primary points is the following:

> Scheme ... has a very simple, uniform notation for everything. Other languages have one notation for variable assignment, another notation for conditional execution, two or three more for looping, and yet another for function calls. Courses that teach those languages spend at least half their time just on learning the notation. In my SICP-based course at Berkeley, we spend the first hour on notation and that's all we need; for the rest of the semester we're learning ideas, not syntax.

Bullshit. Again, I was a TA for this course. You do not spend the rest of the semester on ideas, you spend the rest of the semester on the students being very confused.

This "everything looks the same" property of Scheme and of all LISP-like languages is a bug, not a feature. When the semantics is different, humans need the syntax to be different. In contrast, LISP/Scheme make everything look the same. It is quite hard to even tell a noun from a verb. This makes learning it and teaching it hard, not easy.

Brian is selling a fantasy here. If you think Scheme is so great, look at this nightmare of examples showing the various ways to implement the factorial function in Scheme: https://erkin.party/blog/200715/evolution/

All of this "abstractions first, reality second" agenda is just a special case of what I call "The Pathology of the Modern": the pathological worship of the abstract over the concrete. Everything modernism touches turns into shit. I am done with living in modernist shit and I hope you are too.

I wouldn't have spoken up except for this comment. As a freshman, I took 6.001, the MIT course that Structure and Interpretation of Computer Programs was based on, and I loved it. As a graduate student, I taught 6.001 three times, twice as head TA under Prof. Sussman and once under Prof. Abelson. In addition to helping make up problem sets, quizzes, and exams, my responsibilities included teaching seven or eight one-hour, five-student tutorial sessions per week as well as teaching a forty-student recitation section once per semester. I graded assignments as well. My point is that I have a lot of experience with what students found challenging in the course.

Prof. Harvey's claim rings completely true to me. Students understood the syntax quickly, and spent little time on it. It was not a point of frequent confusion. There were plenty of difficult concepts in the course, but the details of the programming language were not, for most students, among them.

Students who already had programming experience when they started the course often had more trouble than inexperienced students, but mostly because they had to unlearn imperative habits since the imperative features of the language, except for I/O, weren't used until late in the course.

SICP covers a huge breadth of material, from basic computational ideas to algorithms and data structures to interpreters and compilers to query languages to concurrency, and does it in an entertaining and challenging way. Even decades later, I find myself pulling ideas from it in my daily programming work.

I worked at Google for almost twelve years, and I can't count the times I found myself muttering, when reading a design document, "I wish this person had read SICP."

I'm certainly biased, but I would encourage anyone who would like to become a better software engineer to read SICP and study it carefully. Take your time with it, but do read it.

  • I've had an introductory Scheme course in a smaller university, and have experience designing data structures, creating parsers & interpreters, and with multi-threading and networking.

    I was never one to really dig lisp. I prefer the structure and the groundedness of a statically typed systems language (I mostly do systems work). But I took on reading SICP in the hope of finding something new and interesting, and to level up my skills. However, I got bored by the it. Probably made it through more than half of the book.

    It's a bummer because I'm left with the feeling of missing out. Am I not worthy or too obtuse to get what's so great about the book? Or maybe I am in fact not the target audience, having too much practical experience that the book doesn't seem worth my while.

    • If you're comfortable writing interpreters you've probably already picked up on most of the "big ideas" SICP is trying to teach. It's a very good introductory book, but it is still just an introduction.

  • Honestly GP is making two very valid points though.

    Something that Clojure does is differentiating between () = lists of calls, [] = vectors (the go to sequential data structure), {} = maps. This definitely helps the eye to see more structure at a cursory glance. It has a little bit more syntax compared to Scheme, but the tradeoff seems to be worthwhile.

    Secondly, I think it's very healthy to be wary of indirection and abstraction. I'm not sure if I agree with the tone and generalization about modernism, but I think there's a burden of proof, so speak, when it comes to adding abstractions, especially in the long term.

    • I think Scheme works well for the kind of conceptual overview the course is trying to provide. I think there is something to the argument that Scheme syntax is not ideal for readability of larger programs, but I would wager that the bigger reason some students find SICP confusing is the same reason it blows others’ minds - the whole approach is at a higher level of abstraction than most “intro to programming” classes.

    • Yes, I agree these are two good points. I also experienced teaching SICP and would say the overall position of the GP is incorrect and results in a less profound understanding of programming.

  • > Take your time with it, but do read it.

    And do the harder exercises. Really do them, not just read and tell yourself you understand how to do that one and move on.

  • Thanks for speaking up. At this point no one is really presenting any evidence so it’s a necessary evil to offset the Lisp slander even if it is, like the parent comment, not much more than an appeal to authority / popularity.

    Syntax is absolutely neither natural nor unnatural, by nature, to humans, but it’s a fact that fewer symbols to memorize is easier than more symbols to memorize. The problem is a failure to launch. Some people never truly understand that it’s not just syntax, it’s semantics. Data is code, code is data. That’s why it all looks the same. This artificial distinction in “C-like languages” is more harmful for the enlightened programmer than it is helpful. Unfortunately not everyone that reads SICP experiences enlightenment the first time (or ever, I guess?)

    • Information hierarchies are empirically important and are an essential part of communications design. Uniform syntax makes information hierarchies harder to parse, because the boundaries around different types of information all look the same. It's the same reason we have different sized headings, bold text, etc. They are distinct markers.

      So yes, fewer symbols means easier memorization, but you could take that to the extreme and you'll find that binary is harder to read than assembly.

      I think Lisp is really elegant, and the power to treat a program as a data structure is very cool. But scanning Lisp programs visually always takes me a little more effort than most other languages.

      2 replies →

    • I really want to like that idea you're describing, however I've found in practice, there absolutely is a practical difference between code, data and types. I mean, they literally live in different sections of a process. If you design a program that runs on a real machine, and you spend a lot of time thinking what the program should do, how it can put the limited resources of the system to good use -- you absolutely need to think about code and data separately. Mostly think about data, really.

      The one area where "code is data" remains a nice idea in my mind is for metaprogramming. And whenever I've done more metaprogramming than small doses, I've come to regret it later, no matter what the language was. (Small doses of metadata can be done even in statically typed, AOT compiled languages without RTTI).

      The reason is I think, just basic data structures and simple procedures built in to a language allow you to express most everything you need, in a very direct manner. The number of distinct concepts you come up with as a programmer can usually be directly defined in the base language. Metaprogramms won't create new concepts as such, it's only code run in a different phase. There is definitely a case for generic/templated data structures but it seems it's best to use them sparingly and judiciously. Be wary of them duplicating a lot of code, fatting up and slowing down your system at compile time and/or runtime.

Upvoted for an interesting take, even though I disagree with some of it.

I took 61A from bh. Personally, I agree with bh's statement that you quoted. Where I encountered difficulty was applying the ideas in a different context (e.g. C or Java). Brian spent time addressing this precise difficulty (in the last lecture or so), but it still wasn't enough for me.

I do heartily agree with you calling out "the pathological worship of the abstract over the concrete". Knuth's Concrete Mathematics was also bucking this trend (e.g. https://youtu.be/GmpxxC5tBck?si=tRHQmuA4a-Hapogq&t=78). I'm curious, once you came to this opinion/realization, how did your teaching/learning change?

Just an anecdote.

I took CS61A by Brian Harvey in 2009. I loved the course and I actually spent very little time learning the syntax and most of the time learning the concepts.

So I fully agree with Prof. Brian Harvey here.

Does it beat OO Java classes with students crying ? or months spent on warning kids not to mutate an iterator or else you're gonna cry again ?

Mostly kidding but different paradigms bear different pain points it seems.

Oh and lastly, the let-us-care-not-about-syntax is also an argument at Brown edu (krishnamurti and his team IIRC)

That said, I'd be curious to hear what your students had to say about scheme confusing traits.

  • I taught both SICP and Java, and I can confirm Java was far more confusing to students. Classes vs instances, inheritance, polymorphism. Why was everything a class? Don't I just want the computer to do something to some input?

    • And the public static void main and then endless conversations about packages, and public/private fields, that will backfire very pragmatically (at the time) unit test frameworks didn't have a way to call private methods ... Ironically by the time you're done with the basics, nobody has stamina anymore to learn anonymous inner classes.

      The thing is, somehow syntax and some forms of abstractions cast a magic spell on most of the population (at time myself included) .. it's your mental interface to the semantics, so you want more syntax to be able to have more abilities, but syntax composes badly.

      At least to me that's why I enjoyed lisps / lambda calc, it reduces the domain into a more homogeneous space, suddenly more things are possible with less. Although it seems that the mainstream rather enjoys doing simple thing with verbose tools (it does looks like you're doing a lot of work with a lot of advanced terminology) than solving hard problems with APL oneliners (hyperbole).

      Different psychologies ?

    • I don’t think OO should be taught to students who aren’t already familiar with structs and passing functions around.

      If those two things are already well-understood, the nature of OO as a some syntactical sugar and a couple lookup tables is readily apparent.

      Without that background, the terminology seems weird and arbitrary and the behavior magical.

You could also portray this as yet another case of theory trumping practice, which is also symptomatic of modernism.

The idea that a language based on a small, elegant set of composable primitives is inherently better for programming in the large as well has not been borne out in practice.

I won't dispute your experience, but for me the point did hold true. SICP was my first introduction to anything Lisp-like, and by that point I'd done C/C++, a bit of Java, quite a bit of Perl/Python, and of course BASIC.

And I was really surprised how quickly and effortlessly I picked up the part of Scheme taught in the book. Faster than any language I had encountered thus far - Python included.

A funny thing to me is I took CS 50 in '85 or '86 (CS 50 and CS 55 were later split into the CS61X series), and instead of Scheme we used Logo for functional programming.... using Brian Harvey's textbook. He was not teaching the course that semester.

At least part of the goal of CS 50 at that time was to explicitly weed students. They didn't want undeclared students to waste a whole lot of time on CS only to find out they were not going to be accepted into CS. Instead, they went through one hard course to find out. Perhaps that explains why some of it was overwhelming to some students?

> Bullshit. Again, I was a TA for this course. You do not spend the rest of the semester on ideas, you spend the rest of the semester on the students being very confused.

I was a TA on an SICP course at a UK university, disagree with you. The students weren't confused, the simple syntax really helped and, because all the students had good maths knowledge, a functional style was a lot more intuitive than imperative.

FYI, the course has since been replaced with Python programming.

> It is quite hard to even tell a noun from a verb

What?

Unless the list is quoted or something, the first item after the opening paren is always the "verb", yes?

  • There's nothing stopping any other item from being a verb, no? (Not the verb, but a verb.) Anything involving higher order functions?

    • In the context of the verb, everything else is a noun. When you understand what the verb does, then you can care about the difference between a verb and a noun.

      18 replies →

Why would the students be confused? By what exactly?

> This "everything looks the same" property of Scheme and of all LISP-like languages is a bug, not a feature.

But you are mixing up things here. There are things that look different. Most things in Scheme can be understood as function calls and match that syntax, but there is different syntax for define, let, cond, if, and others. Not everything looks the same. What you might actually mean is, that everything is made of s-expressions. That is actually very helpful, when you work with code. It makes it very easy to move things around, especially in comparison to languages like Python, with significant whitespace indentation.

> When the semantics is different, humans need the syntax to be different.

I learned multiple languages before Scheme, and they did leave their scars, but I find, that I do not need syntax to be that much different. Maybe I am not human.

> In contrast, LISP/Scheme make everything look the same. It is quite hard to even tell a noun from a verb.

Is that a feature of the English language? I have rarely had this issue in Scheme. Perhaps it is because I think a lot about names when naming things.

> This makes learning it and teaching it hard, not easy.

Maybe I only had bad classes and lectures before reading SICP on my own, but I found, that I learned much more from it than most teaching before that was able to teach me.

> Brian is selling a fantasy here. If you think Scheme is so great, look at this nightmare of examples showing the various ways to implement the factorial function in Scheme: https://erkin.party/blog/200715/evolution/

And what exactly is your criticism?

That there are many ways of writing the function? That is a property of many general purpose programming languages. For example we could look at something like Ruby, where it has become part of the design to allow you many ways to do the same thing.

Or the richness of programming concepts available in Scheme? Is that a bad thing? I think not. You don't have to use every single one of them. No one forces you to. But am I glad to have them available, when have a good reason to use them.

Surely you are aware, that the page you link to is at least partially in jest?

> All of this "abstractions first, reality second" agenda is just a special case of what I call "The Pathology of the Modern": the pathological worship of the abstract over the concrete. Everything modernism touches turns into shit. I am done with living in modernist shit and I hope you are too.

I don't know where you got the idea, that SICP lauds "abstractions first, reality second". This is not the essence of SICP. SICP invents abstractions, once it shows, that some previous approach was not sufficient. A good example is the whole "develop a package" thing, where piece by piece the requirements grow and data directed programming is introduced.