It’s interesting, SICP and other many other “classic” texts talk about designing programs, but these days I think the much more important skill is designing systems.
I don’t know if distributed systems is consider part of “Computer Science” but it is a much more common problem that I see needs to be solved.
I try to write systems in the simplest way possible and then use observability tools to figure out where the design is deficient and then maybe I will pull out a data structure or some other “computer sciency” thing to solve that problem. It turns out that big O notation and runtime complexity doesn’t matter the majority of the time and you can solve most problems with arrays and fast CPUs. And even when you have runtime problems you should profile the program to find the hot spots.
What computer science doesn’t teach you is how memory caching works in CPUs. Your fancy graph algorithm may have good runtime complexity but it completely hoses the CPU cache and you may have been able to go faster with an array with good cache usage.
The much more common problems I have is how to deal with fault tolerance, correctness in distributed locks and queues, and system scalability.
Maybe I am just biased because I have a computer/electrical engineering background.
Have you seen
"Software Design for Flexibility: How to Avoid Programming Yourself into a Corner" by Chris Hanson and Gerald Jay Sussman
It's from 2021.
I hadn't, that looks excellent.
True. However I find that most junior and even experienced programmers struggle with tactical level coding. I'm really suffering with this right now because the small component I'm tasked with making a small change to is annoyingly stateful and deals with 2 abstractions at once. (It processes files and uses the file system and database to store it's state). I'm shocked how badly it has been thought out. I've spent days trying to avoid doing what has gone before, bits bolted on that make it even more difficult to understand. It really seems that pull request culture has just led to any old crap being approved because no one has the band width to think deeply about the actual code. Bring back in person code reviews !
I find books like SICP interesting and not very useful. I love reading them because I like this stuff, but I don’t get to apply their teachings in real world software. It’s a problem because naturally I want to spend my time reading these kind of books, but if I do that I would be jobless. I need to divide my time between reading pearls like SICP and boring Kafka/Postgres/Golang/K8s/AWS documentation.
If you knew how to design programs you could run it all on a single box and wouldn’t have to design “systems.”
I’m being slightly facetious, but only slightly. If you really think everything is solvable with arrays, you are not going to scale well and of course you’re going to need to throw a lot more hardware at the problem.
You're in luck. Part 5 of the book is about building a virtual machine to run lisp simalated at the register lelvel: https://mitp-content-server.mit.edu/books/content/sectbyfn/b...
Writing a network between n such machines is left as an exercise to the reader.
The article has a broken link for the free copy:
https://mitp-content-server.mit.edu/books/content/sectbyfn/b...
https://web.mit.edu/6.001/6.037/sicp.pdf
I hadn't seen a blessed PDF version until today. Circa 2001, only the HTML version was freely available, and someone converted it to TeXinfo: https://www.neilvandyke.org/sicp-texi/
If anyone wants to work through SICP today, you can run the code in MIT Scheme, or in DrRacket: https://www.neilvandyke.org/racket/sicp/
For anyone wishing to try: the maintainers of MIT Scheme no longer provide a .dmg but you can download and build the x86_64 version of MIT Scheme. The current release (v12.1) works on a Mac running Sequoia with Intel CPU or on Apple silicon via Rosetta. But the native code compiler (not necessary for SICP AFAIK) is a little broken. (Anecdotally it worked on macOS prior to Monterey, so maybe an Apple-supplied dependency changed. Haven't tracked down the issue.)
All of that is to say: if you do not need MIT Scheme and don't want to fuss with compiling it, then Racket might be a better way to go.
one thing to note is that the second chapter's "picture language" is not supported in MIT Scheme in 2024. There used to be a package but it's like 2 decades out of maintenance. In Dr. Racket however, there is a package specifically for working through those problems.
Dr Racket has SICP and HTDP as a teaching pack.
The texinfo version was I believe the source for the really nice HTML version if you want to read it in a browser, but with nice formatting that the MIT original version: https://sarabander.github.io/sicp/
Just dropping in to say that The Elements of Programming Style is worth reading three times — and I have read it many more times than that, and benefitted from it. Here's my review (from 2010) if you're interested: https://reprog.wordpress.com/2010/03/06/programming-books-pa...
I really wanted to like SICP but Lisp throws me off. I love Haskell and Standard ML however! Did others have a similar experience? Might be interesting to read a book similar in spirit to SICP but using a different language as a vehicle (No, I don't want to do SICP in JavaScript).
I really wanted to like SICP and I probably would have if I read it 15 years ago. I started reading it last month and I found it to be too broad. It covers too much interesting mathematical principles and then jumps to the next one right when it starts to get interesting. In other words, it's too shallow.
It probably doesn't help that I've seen many courses/documents that are (in hindsight) derivatives from SICP, so I have the nagging thought "not this again" when a topic is introduced in SICP.
It's written for engineers, they already know the math, but they don't know how to design and implement virtual machines, objects, compilers and whatnot that it shows how to do.
You might be interested in a 1987 article titled "A Critique of Abelson and Sussman or Why Calculating is Better than Scheming" (https://dl.acm.org/doi/10.1145/24697.24706), where the author advocates the use of KRC or Miranda as alternatives to Scheme. I don't know much about KRC, but Miranda is a statically-typed functional programming language that influenced Haskell.
I can identify with that - Lisp throws me off (because I’m not smart enough). But I ended up forcing myself to work through it and learned a tremendous amount because I’m not smart enough to work with a lisp. It felt like I spent so much time just reading through the code that I ended up learning more than I would in a language I’m comfortable with.
There is a Python version of SICP. I have never worked through it or even given it more than a cursory scan so this is not an endorsement more just a link to prove it exists:
https://wizardforcel.gitbooks.io/sicp-in-python/content/0.ht...
I think there is a Python version if that floats your boat
Curious to hear folks opinion on the newer Software Design for Flexibility: How to Avoid Programming Yourself into a Corner (https://www.amazon.com/gp/aw/d/0262045494)?
I've been programming for 25 years and have owned the book for about 10 years. I just recently started to work through it and started with Dr. Racket.
There are things to love about Dr. Racket: hovering over a variable and visually seeing its connections to other places in the code is really cool. But ultimately I was a bit frustrated that it wasn't vs code.
So I stood up an configuration that let me use vs code (cursor actually) to work through the exercises. The LLM integration into cursor is cool as you can give it your code and whatever narrative you wrote and ask for feedback.
I am a tiny way through the exercises but having turned my code, the responses that I write, and the feedback that I get from the LLM into a static site.
It's been a fun way to spend a little time. For sure, I'm not getting the full benefit of working through SICP just with my own thoughts (without the aid of an LLM), but it's neat to see how you can integrate an LLM into the exercise.
My second reading made me dig the footnotes and references, and there's a big world of beauty out there too. IIRC there's a paper where Sussman and some team made a custom design programmable processor to compute celestial bodies properties (trajectories). Mind bending as usual.
SICP helped me understand early on that there were many models of programming, even though I'd learned a limited number in my undergraduate. It was one of the books that helped me feel equipped to read the docs of any language, library or framework and have some notion of how to orient myself.
I don’t quite get the cult status of SICP. I read it and it’s a fine beginner programming book, but nothing more.
Just so we're clear, this is a "beginner programming book" that has you create a scheme interpreter, then a register machine simulator, then a compiler out of your interpreter that will then have its compiled code run on the register machine simulator, by the final chapter.
This is probably the part where you'd step up and post a link to your repo with solutions to the exercises to back up your talk, but generally I only see this sort of casual dismissal from people who haven't actually worked through the book.
I commend your righteous indignation. Made me smile. Flame on!
i'd also recommend "Concrete Abstractions: An Introduction to Computer Science using Scheme" by Max Hailperin, Barbara Keiser, Karl Knight.
I concur, I am learning from it now…
I’m slowly making my way through it a second time and thoroughly enjoying it. The first time through it seemed quite abstract, albeit only because of my completely lack of real world programming. The second time through it a revelation as I now have a strong base of experience through which to understand it (experience which it also, informs!).
I am using Elixir’s Livebook to take notes and complete the exercises. It is very helpful to have a live notebook tool while reading it!
There are some great books, and every book means something different to each person who reads it.
K&R influenced a generation of programmers.
Hennessy and Patterson influence a generation of architects.
etc. etc.
It's not just SICP.
But the greater point: a book can be meaningful, and we can always use more good ones.
I’m working through it now, for someone with a computer engineering, EE or math background I think this is a great resource to get started with CS fundamentals.
> The computer revolution is a revolution in the way we think and in the way we express what we think. The essence of this change is the emergence of what might best be called procedural epistemology — the study of the structure of knowledge from an imperative point of view, as opposed to the more declarative point of view taken by classical mathematical subjects
Ironic, given the increasing use of functional programming in domains where old-fashioned imperative/OO programming used to reign alone.
I think in the context of the book 'procedural epistemology' encompasses all programming, not just what you'd call procedural programming.
Hmm, I don’t think so. Functional programming is definitely based on the “declarative point of view taken by classical mathematical subjects”.
Original version: https://mitp-content-server.mit.edu/books/content/sectbyfn/b...
Javascript version: https://sourceacademy.org/sicpjs/index
And the Python version: http://www.composingprograms.com/
this is not the Python version of SICP. It's a different book inspired by SICP. There's no "picture language" in chapter 2, and there's no "metacircular evaluator" and "register machine" in chapter 5.
SICP is available for free: https://web.mit.edu/6.001/6.037/sicp.pdf
If you want to get it elsewhere, the full info is: Structure and interpretation of computer programs by Hal Abelson and Jerry Sussman (MIT Press. 1984. ISBN 0-262-01077-1).
Programming Pearls is another book that rereads well. It's also short, too, which makes rereading it possible.
> In fact, I’d go further and say that it’s the only computer science book of that age that I’d happily and usefully read again without it being just for historical interest: the content has barely aged at all. That’s not all that unusual for mathematics books, but it’s almost unheard of in computer science, where the ideas move so quickly and where much of what’s written about is ephemeral rather than foundational.
I recall that when MIT stopped teaching with SICP, one of the main claims was that programming now is often not about thinking abstractions through from first principles, and creating some isolated gem of composing definitions. Instead, we interact with and rely on a rich ecosystem of libraries and tools which often have individual quirks and discordant assumptions, and engineering then takes on a flavor of discovering and exploring the properties and limitations of those technologies.
I think now, (some) people also are at the point of not even directly learning about the limitations and capability of each tool in their toolbox, but leaning heavily on generative tools to suggest low-level tactics. I think this will lead to an even messier future, where library code which works on (possibly generated) unit tests will bear some fragile assumption which was never even realized in the head of the engineer that prompted for it, and will not only fail but will be incorporated in training data and generated in the future.
I recall that when MIT stopped teaching with SICP, one of the main claims was that programming now is often not about thinking abstractions through from first principles, and creating some isolated gem of composing definitions.
Which is a category mistake that they actually address in the lectures. SICP is not a programming course, it’s a computer science course. Computer science is not about computers, let alone programming, just as geometry is not about surveying instruments and astronomy is not about telescopes.
When they stopped teaching SICP — in response to the pressure to teach more modern tools — they abandoned their scientific principles to satisfy commercial concerns. They stopped teaching computer science and became a vocational school for the tech industry.
> They stopped teaching computer science and became a vocational school for the tech industry.
Sheldon always said that MIT is a trade school
> SICP is not a programming course, it’s a computer science course.
I don't see what you mean by this at all. Furthermore this doesn't strike me as a useful distinction when a) it doesn't cover most topics labeled by consensus as "computer science" and b) it very clearly does teach a great deal about programming.
Why not say it teaches computer science and programming skills? Why do these have to be exclusive? There's obviously a great deal of overlap in general.
The quote was about "programming by poking" which I take as highly relevant to actual distributed software. It meant (1) systems are more built by integrating many components, and (2) for many reasons, the components are not understood by the integrator and (3) they must resort to experimentation to validate how things actually work.
Unless you have a TLA+ model of all your components and how they interact, I would argue you don't understand your distributed system either, for all inputs.
https://web.archive.org/web/20160505011527/http://www.poster...
I've witnessed how abandoning first principles undermines the evolution of a system. If our mental model of a system is not formalized into first principles (i.e. a high-level specification), then successive generations of engineers will have to re-learn those principles through trial-and-error. They'll introduce mutations and dependencies between the mutations-- and when they leave, the next generation of maintainers will repeat the process. Generations of mutations eventually create a brittle, calcified creature of a system which people fear to touch with a ten foot poll.
I imagine people who were taught SICP would be more respectful, if not inclined, towards a formal articulation of a system's principles.
This philosophy is described in depth in the original 1985 article https://gwern.net/doc/cs/algorithm/1985-naur.pdf and in more accessible language in https://www.baldurbjarnason.com/2022/theory-building/. You can also observe engineers opposing/misunderstanding the need for specification in https://news.ycombinator.com/item?id=42114874
I think just like traditional engineers have to learn physics, computer people should learn these fundamentals for exactly the reason you outline.
Then, when you hit the job market, you learn the ecosystem of what other engineers have built and you work in that context.
In this way, you can eventually reach extreme productivity. Just look at humanity's GDP over the last 200 years.