Why "Structure and Interpretation of Computer Programs" matters (2011)

10 days ago (people.eecs.berkeley.edu)

Prof. Abelson's original lectures are available on YouTube and WELL worth the time to watch. It's unfortunate that this type of granular understanding of CS is seemingly not taught anymore - might help dampen down the hype cycles of late which equate a computer to a divine being of limitless potential instead of a dumb box full of switches.

  • My favorite class in college was my fundamentals of computer systems class.

    It finally clicked how assembly instructions could draw images on a screen and all the magic inside my computer vanished instantly.

    Big fan of dumb switch boxes

I would never get into programming if all I was shown were some quixotic features of Scheme I couldn't use for anything in the real-world. What attracted me to programming was to quickly enable me how to draw a graph of a function, how to make a simple worm-like game, how to dream about creating a flight simulator and drawing the plane dashboard with all its dials and make them move even if the flying part was deep in dreams, drawing a car on a screen with some air arrows to simulate aerodynamics and dream how to build a software for it. But dry string manipulation with weird syntax was not very interesting and in fact rather repulsive.

  • I love SICP, but I will say this: there's a certain class of "great" textbooks that sometimes get recommended by experts, that aren't actually that great for someone learning something for the first time. They get the reputation as being "great" because they are great for people that already have a good basic grasp of the material: They are precise and pithy, and they contain insights that are deep and useful, but hard to appreciate if this is your first encounter with the material. (Kleppner & Kolenkow would be a good example of a freshman physics textbook in this category.) With all due respect, I would put SICP in this category. Which, of course, is a noble and important category, but maybe not the most important category if you're just starting out on a topic.

    • Discussing these textbooks - and more generally discussing education - also seems to reveal a lot of weaknesses in how people think about the world. There's a tendency to think that because something is difficult it's worthwhile. There's a tendency to ignore opportunity costs, or consider alternative efforts. There's a tendency to frame on cool concepts that are intellectually fun and more pleasing to the ego as "real learning," when most CS graduates are likely going to be running into much more trouble on less glamorous stuff like navigating frameworks.

      I'm definitely coming from my own perspective, having initially been self-taught, and then finding myself with the opportunity to go back and academically study CS at a well ranked university. Supposedly, this would fill all of the "holes" in my knowledge (you see this sentiment a lot). I found the classes fun, and I did well in them. But I was also constantly trying to find usefulness in them when it came to work I actually was doing, and didn't find any. Though I don't regret doing it as an interesting life experience, it was honestly a waste of time and money when it comes to my CS skills.

      Which isn't to say that SICP is useless for everyone, or that no one will get value out of it. But reading the article in the link, as well as all of the replies, it's telling that people are writing so many paragraphs but aren't able to say anything concretely. Even multiple paragraphs accusing people of looking for excuses not to do it - but not providing any concrete examples of its usefulness. This should set off red flags.

      Yes, there are people who are completely clueless about core concepts. Though SICP is obviously not the only place to learn about those concepts. Further, most people hanging out in places where those concepts are discussed and are considering whether or not to do SICP in their free time likely have been exposed to the concepts already (and might already have a pretty good grasp on them).

      There always is a bit of posturing and ego involved when some of these things come up, and they often lead to people giving very poor advice.

  • SICP uses Scheme in the same way all programming must use some language, but it's not a book that is primarily about Scheme. The problems in this book are challenging in any language and the ideas around computation are more or less universal -- see editions and derived books in Python and JavaScript[1][2]

    Also, YMMV: I have a math background and got sucked into programming because the appeal of being able to hold an idea in my hands by writing a program that I could poke and prod and play with was really exciting. The quixotic spirit of the book fed my enthusiasm. (And this is neither here nor there, but I think pedagogy in a first course should probably skew quixotic)

    People get into programming for all kinds of reasons -- I recognize that SICP isn't the right book for everyone, and that there is a lot of elitism around this book. Nobody should feel bad about not getting much from it, and I think it has severe pedagogical flaws, but I'm very glad and grateful that it exists because for me, personally, it was exactly what I needed.

    [1] http://www.composingprograms.com/

    [2] https://sourceacademy.org/sicpjs/index

  • Quixotic features like functions and variables.

    Edit: Sorry, was cranky from being hungry. I take issue with “useless in the real world.” The first chapters introduce variables, functions, recursion, and lambdas, and not much more than that. That’s the beauty of the book. Flexible ideas that are immensely useful and form a great foundation for learning computing. It’s not the best total beginner book, I’ll admit, but it’s a great beginner-intermediate book for those who seek mastery.

    • This seems like a misunderstanding of what other people find limiting. The problem some people have with this book is that it’s about computing in isolation. Scheme is an island with text-based I/O (as far as the textbook is concerned). You interact on the command line and do calculations. The ideas you learn about are deep, but internal, disconnected from other systems. There are engineering problems, but they aren’t about building systems, they’re about doing calculations or simulating systems using math. Functions and data structures and a bit of text data is all there is.

      This is great in its own way, but nowadays, there’s a preference for a programming course that’s more extroverted, that lets you build interesting things by including a program as one component of a larger system. I believe even MIT switched to an introductory course where they program robots using Python, or something like that?

      3 replies →

  • The danger in demanding to just be taught how to be a good code monkey is that that increases your risk of getting stuck just being used as a code monkey.

    My intro CS class was taught in Scheme. I haven't found what I learned in that class to be quixotic at all. Instead, I view it as setting me up with a strong foundation that colleagues of mine who learned in a more "popular" language lack. It's put me at a permanent advantage for designing and building software - even decades later, I find that there are ways of decomposing problems that I can understand easily, and colleagues of mine who learned on Java still have trouble with, because they simply lack the "design vocabulary" that would enable them to think about the problem in the right way.

    We never again used the language past that first introductory course, but I still don't think it was a waste of time, because it allowed us to cover so much ground so quickly. In 3 months we went from basic fundamentals to building our own object-oriented programming system from scratch. That's amazingly powerful. A deep knowledge of what object-oriented programming actually is, and how it works under the hood, is usually considered an advanced and esoteric concept that few people really understand. Fast forward about 15 years, and having that kind of knowledge in my head allowed me to take a job at a Java shop, having never touched the language previously, and then within just a few short months have a deeper understanding of how Java works than colleagues of mine who had been using it on a daily basis for 20 years. So that they were coming to me for help with Java problems, despite having an order of magnitude more experience with the language.

    Rewind back to school, and it's the same story. The second class in the freshman curriculum used C++. It was not a course in C++, mind - it was a class on algorithms and data structures. Learning C++ was just the first couple of weeks. And learning it mostly consisted of being taught the syntax and the build and debugging tools. The semantics for everything - pointers, classes, templates, etc. - took a negligible amount of time because it could be explained to us in terms of concepts we had already learned by building ourselves - in a 3 month intro class.

  • When I was first introduced to computers, I was shown BASIC and Logo (Apple II plus). Logo felt a lot like a LISP (at least, that's how it was presented to me... ) with a very easy way to make graphics (turtle model).

    I couldn't really get into Logo- it felt too indirect, too computer-sciencey, so I went into BASIC and later Machine Language to learn how to build games (I was influenced by Choplifter, Lode Runner, Wizardry, and Ultima). It wasn't until some time later that I learned LISP and began to appreciate functional programming and the turtle model (I still am amused at how much I learned on that original Apple II that still applies today to tech like SVG).

    I reflect a lot on how Norvig was a LISP guy and then when he saw what was happening in scientific computing, pivoted to treating Python like LISP (https://www.norvig.com/python-lisp.html and https://www.norvig.com/lispy.html) although I don't know that anybody really anticipated we'd have systems like Jax which really turn functional programming in an imperative language on its head.

  • Very good point. That was literally the magic of early Basic. One could do something quickly. And the imperative nature of the language gave a simple point of attention mental model. I feel that point is lost in many criticisms.

  • I always dislike it when people emphasize "applications", as if those were the only valuable things to learn. Nothing in my professional and academic life has been as valuable, as a strong conception of various theoretical concepts.

    What SICP is about, is programming theory. How data structures can be formed and manipulated to solve abstract problems and how these programs are executed.

    Sure, nothing in this book will tell you the best way to program a video game, but the presented concepts are of genuine importance and can be seen in a wide area of circumstances. Ultimately the book want's you to think more abstractly, which is great way to understand things.

    • GP mentality is prevalent and the reason why the "big ball of mud" article and the "worse is better" blog post are so relevant. People don't want to understand computers and computation they just want to get some stuff done. Companies just want to put out a product. They never seem to realize that following their noses and not thinking too much about the underlying tools is what landed us with this mess of ever changing, overly complex frameworks and nightmarish levels of insecurity increasingly surrounding more and more critical infrastructure.

      2 replies →

I always see people gush over this book, but is it still worth reading for someone that already has a ton of experience programming?

  • I started reading it around a year ago with the personal goal of doing every exercise. I'm not done yet (almost done with chapter 4). It has definitely taken a lot of my time, but it really has changed my thinking about a lot of language constructs I find in other languages.

    For instance, the part about tagging objects with their type reshaped my thinking about static type systems in general. Static typing, for example in C, is essentially just moving the location of the type tag from existing at runtime within the struct, to the "analysis" phase of the compiler. It's a pretty simple idea, but it made the "degree of dynamism" tradeoff click in my head. All the information _has_ to exist somewhere, and the only question is where. And Scheme is just at an extreme where the _everything_ is stored dynamically.

    • > Static typing, for example in C, is essentially just moving the location of the type tag from existing at runtime within the struct, to the "analysis" phase of the compiler.

      See also "shift left"

      > All the information _has_ to exist somewhere, and the only question is where.

      Not entirely sure what you mean about this, but not all type information has to exist somewhere. Sometimes things get encoded into a type that might never be represented otherwise -- like whether an integer is a width or a height, or whether a string is a name or an address.

      22 replies →

  • "Don't cast your pearls before swine".

    When I was younger I used to passionately defend those things I've seen as beautiful, but after years experience talking with people passionate about their fields and learning and those who never will be: If you lack the innate curiosity to explore those things others have declared marvelous, then this book will offer you no value.

    Every time I crack this book open I get excited and I've read it multiple time and one most of the exercises. I can think of few other books that really expose the beauty and simultaneously strong engineering foundations of software.

    You have "tons of experience programming" and sound like you've already decided you know what needs to be known (otherwise why even ask rather than just read it free online), I doubt this will offer you anything you haven't already seen before.

    • > If you lack the innate curiosity to explore those things others have declared marvelous, then this book will offer you no value.

      > Every time I crack this book open I get excited and I've read it multiple time and one most of the exercises. I can think of few other books that really expose the beauty and simultaneously strong engineering foundations of software.

      ---

      https://news.ycombinator.com/item?id=7667825 and others)

      > Every programmer occasionally, when nobody’s home, turns off the lights, pours a glass of scotch, puts on some light German electronica, and opens up a file on their computer. It’s a different file for every programmer. Sometimes they wrote it, sometimes they found it and knew they had to save it. They read over the lines, and weep at their beauty, then the tears turn bitter as they remember the rest of the files and the inevitable collapse of all that is good and true in the world.

      I recommend (not ironically) Double Binded Sax by the group named Software.

      1 reply →

    • > otherwise why even ask rather than just read it free online

      Not GP, but my time is limited, so asking "is this something an experienced programmer would find worthwhile and insightful" is a fair question.

      2 replies →

    • Might find it beautiful, but I'm also just f'in busy. Why do you think that if I enjoyed it I would've already done it? Enjoying things is great but it's not my main desideratum for doing something

      1 reply →

  • It definitely is a "classic" book for a good reason.

    I think it really depends on your actual formal education, how valuable this book will be to you. If you have a CS degree basically everything in there should have been covered during your studies, you already know how to operate on trees, recursive algorithms and how to build an interpreter. The main value to you would have been seeing it all come together in one place.

    If you don't have that kind of education I believe it is extremely valuable to see programming from a theoretical perspective. The book is very good at laying out a cohesive narrative of how you go from very basic structures to complex programs and how these programs can be executed by a computer. The highlight definitely is the implementation of lisp in lisp.

    There were also chapters, mostly towards the end, which I think aged quite poorly and seemed mostly irrelevant. I don't think there is much lost by skipping them.

  • I think it is, and if you don't want to take my word for it, John Carmack thinks the same :)

    There's an old video [0] where he talks in-depth about his explorations of functional programming. It's perhaps a bit more about Haskell than about SICP, but in it he's also quite enthusiastic about what a veteran programmer can still learn from this book.

    [0] https://youtu.be/1PhArSujR_A?si=OD8pGYsoGC7RXPVG&t=125

  • Experience in software development isn't linear so depending on which path your experience has taken it could be very insightful and useful, or it could be stuff you already know.

    I'd say for the vast majority of developers, experienced or otherwise, it's a good read.

  • That book was my first programming class and programming ever: CS61A at Berkeley. When I started taking it, one of the TAs said that the ideas in the class were wasted on us - they seemed simple but we wouldn't grasp the fullness of the ideas until we had more experience. He said the class should be required to take twice: your first and last class.

    It gives you basics of things like recursion and message passing that are easy to use immediately (well, once you figure them out -- it took me two weeks to be able to write even the simplest recursive function), but there are large conceptual things you won't really see the depth in until you have more experience. The last project is the meta-circular evaluator - writing a scheme program to interpret scheme programs. It is difficult to understand that without having a lot of other background.

    Even then along the way learning things like exceptions as implemented through call/cc might be a little too much for a beginner programming. The book is in some ways talks about concepts way outside of a beginner's comfort zone.

  • Whether it's worth reading isn't a question others can answer for you, but "a ton of experience programming" definitely doesn't imply it isn't worth reading as it's perfectly possible to get through an entire programming career without encountering the ideas and ways of thinking that you'll find in it.

  • Depends on what you learned during that "ton of experience programming." My only regret was that I had, but stupidly ignored, the MIT course notes that preceded publication of SICP. I didn't realize what I had missed until many years later when I sat down to work my way through SICP. I coulda been a contender.

  • Depends on the kinds of experience. If you have experience writing compilers and interpreters - probably not a lot. If your experience is in application development you might learn a lot.

    I worked through it after years of practical experience as a self-thought programmer, and I learnt a lot (and found it quite challenging, especially the mathy parts).

  • That depends entirely on what kind of a ton of experience you have. If you have written Java/PHP/Python/JS for 20 years, SICP might teach you lots of new tricks. If you have worked a lot with functional languages, probably fewer, but still probably some in later parts of the book.

    • I'd worked exclusively with functional languages and assignment operators implemented as lambdas blew my mind more so than all the monads in Haskell.

      1 reply →

  • I used it as a teaching aid to help colleagues from our application teams get the background and skills to work on our core platform. I certainly got a lot out of it because I had to do all the exercises, and I think if i hadn’t had to prepare like that I would have skimmed more and gained less. But I already had a background that covered a lot of the same areas.

    So it is going to depend a lot on your background and the effort you put in. It may be better done as part of a reading group where you can discuss the exercises than on your own as some are meant to highlight why certain approaches are hard and are not commonly used.

  • I'd say it is less about your experience with programming and more about your interest in it. SICP has quite a profound style that's in between academic and poetic. For me, it was both fundamentally informative and inspirational. So, if you feel like structuring your computer science foundation and like an imaginative approach to programming and math that favors aesthetics, give it a try.

  • I’d say read the first chapter. If it doesn’t excite you at this point in your career it might not be for you and that’s ok.

    I’d say it’s actually more valuable to people with programming experience. It gave me a greater appreciation for solving complicated problems in elegant ways. And perhaps ambition to solve other more practical but still complex problems in similarly elegant ways.

  • I would say yes. I read it when I was already an experienced programmer and I still found it worth it. Scheme is one extreme in terms of styles of programming languages, and it allows the authors to present a certain way of thinking about programming that was still new to me that is natural in Scheme.

  • I’d personally say especially so. I’m guessing those taking it as freshman are missing out on 75% of the good stuff.

    It’s free online. And YouTube has lectures from the authors- presented in all their early 80’s glory.

  • No. If you want a deeper understanding of programming, write your own static analysis / theorem prover.

I always found the first half of the book a light read, an exciting read, it was as wonderful to read for me as Lord Dunsany, I sped through it.

When it started to get to object orientation I started having problems following. It just didn't make sense. Maybe I should try again, but it just always made me feel that for my particular mind functional thinking was better.

  • From personal experience, I can say a person can build a fruitful bread-and-butter earning programming career on the first two chapters of the book, provided you solve literally all the exercises. Such is the density of know-how and design context packed in there. This also makes the book a challenging read. I feel like the math-y content is also not for everyone. After all, it was aimed at MIT engineering undergrad students who are expected to have a baseline mathematical felicity well above the average high school level.

    • I find the difficulty of the chapters goes as the square of their number. Viz. Chapter 5 is 25 times as hard as chapter 1. I also find that basically no one goes past chapter 4. I've only ever seen one good talk on it and the guy was so far down the esolang rabbit hole that he had an IBM apl keyboard.

      3 replies →

  • Hm... I read half of the book (with exercises) and stopped. I don't remember why, but it was probably OO for me too.

In addition to the free book online, YouTube has original lectures from the early 80’s- complete with quirky humor, super early attempts at graphics, and late 70’s fashions all around.

Oh,and educational too!

  • And the best introductory lesson ever where they explain you what is programming.

And here i thought the goal of SICP was to scare off folks who were getting into CS because it was trendy rather than because they enjoyed it...

Seriously, it was a really valuable foundational course. But 100% it scared some folks to other majors.

  • > And here i thought the goal of SICP was to scare off folks who were getting into CS

    Well, the acronym is pretty close to SCP...

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.

      1 reply →

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

      2 replies →

    • > 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?)

      4 replies →

  • 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?

      2 replies →

  • 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?

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

The best lesson I took from SICP (which I read years after Iw as a competent programmer) is that the very moment you write your first function you are in effect creating a DSL for solving you domain problem.

It truly levelled me up as a programmer when I was hit with that insight.

I have never gotten past the first few pages. Had it ever been a mandatory class in my education, I would be working with something else today.

Every time I read about SICP, I get frustrated all over again about Javascript. It could have been Scheme and all web development would have benefited.

  • The only way it would have "benefited" would be that the web would only be developed by lisp programmers.

    To the vast majority of programmers, syntax matters. C-style with brackets, or python whitespace, or Ruby do/end, these fit better the brains of the majority of programmers. Perhaps not the majority of HN readers but the majority of corporate devs.

    Another example of this is Erlang and Elixir. Elixir adds a couple of features over Erlang, macros and protocols, but Erlang does everything else. What made Elixir take off where Erlang didn't, after decades, is that Elixir has a syntax that people are comfortable with. Erlang has a syntax that will summon Cthulu.

    • To be fair, what made Elixir take off, other than syntax there is also the developer experience overall, including documentation, package manager, unit testing framework out of the box, web-framework initially inspired by Rails etc.

      Though, slightly off topic, but worth mentioning, that both Erlang and Elixir communities support each other very well. For example, now not only elixir is built on top of Erlang, but also Erlang adopts some things from elixir, such as monadic expression `with` from elixir inspired `maybe` in Erlang, or starting OTP27 Erlang is using ExDoc introduced by Elixir to generate documentations.

    • Is it an innate property of humans that the curly-brace style is more natural? I wonder if in an alternate universe where Lisp took off as the browser language people would find it more natural instead. It seems like somewhat of a chicken-egg problem.

      64 replies →

    • "The only way it would have "benefited" would be that the web would only be developed by lisp programmers."

      Considering the state of the web I do not think this is making the argument you intend.

    • I agree with most of what you said here but I want to emphasize that this is not necessarily a good outcome. Fitting the brains of corporate devs is not a metric to measure if your goal is to make the best tool for the job - the majority of corporate devs are extremely mediocre at their job even with a language that they’re not scared of.

      All that to say, I completely emphatically agree with the original comment. The world would have been so much better off with Scheme as the language of the web.

      1 reply →

    • > To the vast majority of programmers, syntax matters. C-style with brackets, or python whitespace, or Ruby do/end, these fit better the brains of the majority of programmers.

      You have no idea whether this is actually true, or whether people have just fit their brains to what is out there.

      The idea that programming language syntax fits people's brains rings untrue for anyone who has watched beginners struggle with it, or remembers being one.

      1 reply →

    • When Lisp was popular, developers learned it as easily or easier than any other language.

    • >The only way it would have "benefited" would be that the web would only be developed by lisp programmers.

      Millions have learned javascript because it is the technology of the web. Are they better off?

      So many people have been introduced to programming, computer science, and programs through the abstractions provided by javascript, and that sucks

    • > To the vast majority of programmers, syntax matters.

      And yet, when you tell them the reasons, why some other syntax than their Java/PHP/Python syntax would be better, they usually counter with "It's just syntax." or "Every language can achieve the same result, why care so much about syntax." or similar.

      > C-style with brackets, or python whitespace, or Ruby do/end, these fit better the brains of the majority of programmers. Perhaps not the majority of HN readers but the majority of corporate devs.

      I would need a source for that.

      I think most programmer's brains have simply not been exposed to other syntaxes much or much too late, when their brain already calcified the C-style syntax. Or they don't actually care.

    • Significant white space would have been a disaster on the web.

      As much as everyone poops on js it is a very forgiving language for embedding.

      1 reply →

    • There is so much begging the question in this thread that it’s absolutely mind-boggling.

    • People aren't born familiar with C style syntax. Quite the opposite: many people struggle with it for a long time! Back in the day it super common to get frustrated because you missed off a semicolon or something. Nowadays IDEs probably help, but what's the point of syntax that the computer could write for you?

    • Very much a personal anecdote, but I spent about a month earlier this year seriously learning various Lisps (CL, Racket Scheme, Clojure). I stopped when it clicked for me - Lisps are a mess. Everything I wanted from Lisp I found in Haskell.

      I'm reasonably confident that all the anecdotes you hear about 10x improvements from switching to Lisp are just programmers learning about functional programming and good design patterns for the first time. But those aren't contingent on using a Lisp, and I'd argue using Lisp brings an enormous amount of cruft and baggage that makes FP seem far more alien and difficult than it needs to be.

      6 replies →

  • As someone who's both versed in Lisps (CL, Racket, Scheme, Clojure) and JavaScript: thank god.

    It's like the Lisp crowd can't be honest with itself and not realise the serious shortcomings of lisp projects are: maintainability.

    Every single lisp project out there, hell this also applies to Haskell, is so radically different because everybody's too busy reinventing its own abstractions and macros (and language extensions in case of Haskell) that you just throw your hands up in the air in dismay.

    It's like the Lisp crowd, that can barely attract like-minded people to collaborate on some simple open source projects out there so you get 20 broken JSON parsers, cannot see the link between that issue and industrial lisps.

    I love lisps, they are fun, they have their place in the industry when you leverage them to their core strengths.

    Try to ask yourself: why does PHP has more quality killer-software than all of lisps combined?

    • > everybody's too busy reinventing its own abstractions

      Isn't that the problem with Javascript too, though? Javascript isn't good enough, let's all use jQuery. No, jQuery isn't good enough, let's all use Vue. No, Vue isn't good enough, let's all use Angular. No, Angular isn't good enough, let's all use React. No, React isn't good enough, let's...

      1 reply →

  • JavaScript was originally developed in two weeks due to time constraints from Brendan Eich's employer. It would probably have just as many design mistakes if he had stuck with a scheme-like syntax instead. It's just hard to create a well-designed language in such a short amount of time.

    • Yes, Javascript is one of the seminal "sales already signed the contract" situations in tech.

      Given the circumstances, it's amazing javascript isn't way worse.

      1 reply →

  • R5RS Scheme (standardised in 1998) didn't even have structs. To make anything like the DOM practical, you'd have needed some non-standard extensions that could well have ended up being a mess anyway.

FWIW the book has moved to https://mitp-content-server.mit.edu/books/content/sectbyfn/b...

The old url at http://mitpress.mit.edu/sicp/full-text/book/book.html is now 404, and most of what you find on that site will try to get you to do an "eTextbook rental".

It is a good book for someone who is familiar with programing computers. It is not the best way to introduce the concepts behind writing software to someone who has never written a computer program. The very beginning does the book disservice

> A computational process is indeed much like a sorcerer's idea of a spirit. It cannot be seen or touched. It is not composed of matter at all. However, it is very real. It can perform intellectual work. It can answer questions. It can affect the world by disbursing money at a bank or by controlling a robot arm in a factory. The programs we use to conjure processes are like a sorcerer's spells. They are carefully composed from symbolic expressions in arcane and esoteric programming languages that prescribe the tasks we want our processes to perform.

Not everyone appreciates that kind of language and the suggestion that software development is some kind of alchemy that can only be understood by the chosen ones is the kind of bullshit that makes people loose interest. It actually projects an amateurish not professional image of the profession. I always found the SCIP crowd unbearable. Which is sad, because there is good information and solid knowledge in that book.

  • There is a lot of “we’re nerds, and we own it” in that book. I suspect it was at least somewhat a response to the contemporaneous “ewww computer nerds are the worst kind of dweeb” nonsense that was happening in schools in the 90s.

    Personally? I love how it’s written. I find it clever, engaging, and that it uses clever analogies and examples, with a theme running throughout. The little comics provide some levity as well.

    I guess, to me, thinking of programming as alchemy effectively levels the playing field a lot. It means nobody is “born with it,” unlike looks or a straight nose or anything like that. It’s all about learning.

    That’s how I read it, anyway.

    Amateurish? Maybe. But, and this is important: we were all amateurs and it’s an intro to CS book. By definition, the people reading this book should be amateurs.

Sadly my first exposure to programming was in FORTRAN on a mainframe (when I took a summer course at a college in 8th grade). I could not initially make heads or tails out of fortran or the imperative approach, but I knew it was magical. Eventually bought a VIC-20 and other computers later.

By the time I was ready to start college was well versed in a number of (imperative) programming languages, data structures, algorithms, etc. However was exposed to SICP in college and fell in love with both the book and emerging functional languages (this was the late 80s).

SICP remains my favorite CS / programming book of all time.

> most introductions to computer science use whatever is the "hot" language of the moment...

So the coming introductory courses will use JS + LLMs?

Can someone compare it to PAIP? I assume SICP handles functional programming ans CS basics and PAIP is more about programming practice in general?

  • Similar themes. SICP is a little more academic. You build a compiler, do more math, etc.

    PAIP also focuses more on Common Lisp specifics.

    • Different audiences too. SICP is meant for first year college students with little or no CS or programming experience. PAIP assumes no Common Lisp experience, but it's not an introductory text for CS. It's an introductory text for GOFAI and Common Lisp.

      1 reply →

I had been programming profesionally for 3 years (since age 15) when I took "SICP" at MIT in 1980 (we used LISP; Scheme would come a few years later). The course is designed to appeal to the ego of the professors who teach it, and it is designed to mold MIT students into AI researchers which is the whole point of the MIT curriculum - -

1. They taught a bunch of extremely advanced concepts like infinite lists of prime numbers where the 'CAR' and 'CDR' functions could be used to iterate down the list, which calculates the next prime number on-demand.

2. At the end of the course, they made the horrific mistake of encouraging students how to write their programs in LISP and then embed the LISP code into other languages, such as Algol, which produces the most extreme spaghetti code in the history of mankind!

The problem with SICP is that it teaches many advanced language concepts but the students are unprepared to absorb them and haven't ever struggled with the types of problems these advanced concepts are meant to solve! It's like showing a peasant farmer how to drive a modern combine before they've ever tried ploughing their field with a horse plough! I can pretty safely say, as a systems programmer, I have used exactly zero of the concepts taught in SICP back in 1980.

But most importantly, when professors teach SICP, they can feel good about themselves because they get the misguided impression that they are teaching something that grows their student's capabilities as a programmer and when talking to other professors teaching introductory computer science, the SICP professsors can say, "look at this cool shit my students did - i bet your students wish they could write shit as cool as this!" - end of story.

Incidentally, I never went to class and got an "A" in the class. It was annoying to have to take this remedial brainwashing class after already taking 2 other CS classes (including introduction to programming and assembly language programming) at the University of Illinois.

> We'll find out pretty soon whether the course can survive my own retirement.

>> (Footnote: Nope. Berkeley's new first course for majors uses Python...)

This is the saddest part of the whole post. Taking the intro course in Scheme set me on a path of thinking about computing in a whole new way. While they try to teach the same concepts with Python, it's just not the same thing as using a truly functional language.

A huge loss for Cal students for sure.

People who complain about parentheses have never tried structural editing. Change my mind!

  • I complain about parentheses, and yet I'm building a structure editor[1]. Two complaints about parentheses:

    - Parentheses obscure the structure of the language. When different syntax is used for different parts of the language, it's easier to visually scan the code. This is simply because punctuation/arrows/etc. visually stand out more than plain identifiers.

    - Parenthetical languages have just as much syntax as non-parenthetical languages, it's just a shittier syntax. Try writing (let (x 1) (y 2) (+ x y)) and see what happens: it's a syntax error. Look at the indentation rules in DrRacket: there's let-like, cond-like, etc., because all of those constructs have different syntax. But it all kind of blends together in a sea of parens.

    This weakness of paren-heavy languages is also their greatest strength, though. Since the syntax is so generic, it's easy to extend, and these language extensions can be indistinguishable from the base language. That's a big deal!

    BTW, what structure editor would you recommend? Which have you tried?

    [1] https://github.com/justinpombrio/synless

    • I run emacs, so I messed around with paredit and friends.

      I can understand your pov as a professional coder, doing enough coding that you can really master the syntax of your language of choice. I code occasionally for scientific research, and the less syntax I have to remember, the better. Little syntactic constraint in combination with structural editing really is a killer feature in my context.

      1 reply →

  • I tried Racked with the recommended IDE setup (VScode), does that have structural editing?

    Here are my notes from 2023-07:

    https://docs.racket-lang.org/more/index.html

        * okay, seriously. functional programming is nice, but these fucking parenthesis are ridiculous. the VSCode extension is okay, but doesn't help at all with formatting, etc.
        * "car" and "cons", yeey, but "first" would have been so hard?
        * the whole "define x 'x" is also meh.
        * no return, so sometimes something just takes the last one and returns.
        * there's string->url ... why not string->parse-url .. no, would have been too verbose. MAYBE YOU COULD HAVE SAVED SPACE BY OMITTING THE FUCKING PARENTHESES
        *
    

    / end notes

    ehehe ... well ... I think I will keep trying it again every few years. is there a pythonish version, where indentation matters and no need for wrapping parens?

    •     * there's string->url ... why not string->parse-url .. no, would have been too verbose. MAYBE YOU COULD HAVE SAVED SPACE BY OMITTING THE FUCKING PARENTHESES
      
      

      string->url is consistent with the way they do things in Racket. Note in that same document you linked the use of number->string and string->number, the -> indicates a type conversion. Along with string->url there is also the reverse, url->string, and some other conversion functions. That consistency is actually pretty nice, it means you can guess and check ("I have a string and want a url, will this work?" Oh, great it does!) or guess and search the docs before checking with the REPL or whatever.

      https://docs.racket-lang.org/net/url.html

          * "car" and "cons", yeey, but "first" would have been so hard?
      

      car shows up once, cons not at all, but he does use cdr. first, second, and rest are available, I don't know why he didn't use it in this demonstration. If you want to use first, go for it.

    • > these fucking parenthesis are ridiculous

      They're just different. And once you've come familiar with the language, you miss s-expressions everyday, because they're just that easy to work with, especially with something like paredit. Why? because the grammar is easy to parse and reason about. The whole code is a tree. And evaluation is mostly working from the leaves to the root.

      > "car" and "cons", yeey, but "first" would have been so hard?

      It comes from the nature of the language. "cons" is to construct a pair of values, and "car" to get the first one, while "cdr" returns the second one. But lists are composed of cons cells (check how it works), and in that case you could argue for "head" and "tail" for the function names. But "car" and "cdr" were first and you could alias them easily.

      > no return, so sometimes something just takes the last one and returns

      The computing paradigm is expression evaluations, not sequence of instructions (although sequencing is there). An s-expression is always equivalent to something, and that something is what you're computing. Something like (first '("name" "email")) is the same as "name". Or (if (> x 0) :pos :neg) with x = 5 is the same as (if t :pos :neg) and the same as :pos. [0]

      No return is needed. It's tricky when doing iteration, but whenever you're doing sequencing (they mention that in the docs for CL), the last value is equivalent to the whole thing.

      [0]: https://en.wikipedia.org/wiki/Lambda_calculus#Reduction

      3 replies →

    • Your notes indeed suggest that you've not been using structural editing.

      Aside from that, you could have tried to use `first` instead of `car`. It would've worked.

      And yes, there happens to be a pythonic version named `Rhombus`, which is the flagship language of the racket system.

    • > but these fucking parenthesis are ridiculous

      I thoroughly agree. I am deeply into functional programming, but syntax built entirely around endless nested parentheses has never felt like anything but a nightmare to me. Doubly so because even in 'clean' code it's reusing the same syntax with what are for most coders three clearly different logical concerns (defining functions, listing statements to execute in order, and invoking functions).

      2 replies →

It's an interesting text for sure, and even became a bit of a meme, but I think SICP has only contributed to the trend of overabstraction and increasing inefficiency in software.

I want a searchable resource where I give my inputs and desired output and brief description of the algorithm and it gives me the algorithm and code.

Same with AOCP, but I greatly prefer scheme to MIX.

Otherwise these works just seem like a doomsday rebuilding references rather than knowledge with any practical presentation.

  • >I want a searchable resource where I give my inputs and desired output and brief description of the algorithm and it gives me the algorithm and code.

    It sounds like you'd like to outsource your problem solving and thinking. Some things require work, and from that you learn and grow, which is the greatest reward.