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.
There are still jobs where people write frameworks, database engines or version control tools. Those jobs require heavy CS and algorithms, data structures day to day. But there are less of those jobs nowadays as no one is implementing db engine for their app they just use Postgres.
Other jobs that is vast majority is dealing with implementing business logic. Using database with understanding how it works in details is of course going to produce better outcomes. Yet one still can produce great amount of working software without knowing how indexes are stored on disk.
Also a lot of CS graduates fell into a trap where they think their job is to write a framework - where in reality they should just use frameworks and implement business logic- while using CS background to fully understand frameworks already existing.
> while using CS background to fully understand frameworks already existing.
Most frameworks today are so complicated that you typically cannot understand them fully, and even understanding them somewhat partially is more than a full-time job.
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.
I don’t find them useful in the sense of directly applying practical techniques in my day job, but I consider them somewhat necessary background reading to get into the right state of mind. You can very quickly tell when someone never acquired any academic knowledge in this area (or never played with functional languages or similar pastimes) - you can’t explain to those people why modifying global variables all over the place in a large program is a bad idea and other things like that. They just nod along skeptically and then somehow keep stumbling into the same kind of mess over and over.
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.
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 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/
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.
The texinfo version was I believe the source for the really nice HTML5 version if you want to read it in a browser, but with nice formatting that the MIT original version: https://sarabander.github.io/sicp/
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 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).
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 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.
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:
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.
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.
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'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.
I took cs61a at Berkeley as my very first computer science class I couldn't program I never tried to so scheme was my first language.
My ta told me that everybody should take the class twice when you first come in and when you're graduating.
When you first take it especially if you know other languages like C at the time you don't get the full depth of the problems you're given a great introduction and you think you understand everything but you don't realize the depth of complexity. Message passing the metacircular evaluator, continuations as the basis of all flow control, etc
You think they are neat tricks that you understand the curriculum because you can do the homework you don't understand how those neat tricks are really the basis of everything else you'll do.
When you're graduating you've had time to go through all your classes you realize just how foundation was principles are and you get so much more out of the book.
Well I didn't take the class a second time I need help grade and TA for a couple semesters.
I work as a quant developer and in trading now and even though my field has nothing to do with that I still think it's the basis of me as a developer.
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!
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 disagree since the book is using a functional programming language to advance the idea that CS is about procedural epistemology as opposed to the declarative stance of maths.
The idea that a 'procedural programming paradigm' exists in contrast with a 'functional programming paradigm' is blogspeak imho.
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.
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).
My favourite part of SICP and something that has stuck with me for years is the idea of "wishful programming". That is where you build something top-down by simply wishing you had the lower-level routines. Then, of course, you actually go and build those lower-level routines until you reach the bottom. I find this way of thinking works really well with test-driven development. Write a test against functionality you wish you had, then go and fulfill that wish. Most developers seem to build stuff bottom-up and then end up with something that isn't really what anyone wished for.
> 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.
> 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.
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.
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.
> these days I think the much more important skill is designing systems
That's true, but that doesn't mean that there is no value in having an understanding of how established technology works under the hood.
> What computer science doesn’t teach you is how memory caching works in CPUs.
That is also a very good point. There is a lot of daylight between the lambda calculus and real systems.
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.
Well CS and software dev in trenches moved a bit.
There are still jobs where people write frameworks, database engines or version control tools. Those jobs require heavy CS and algorithms, data structures day to day. But there are less of those jobs nowadays as no one is implementing db engine for their app they just use Postgres.
Other jobs that is vast majority is dealing with implementing business logic. Using database with understanding how it works in details is of course going to produce better outcomes. Yet one still can produce great amount of working software without knowing how indexes are stored on disk.
Also a lot of CS graduates fell into a trap where they think their job is to write a framework - where in reality they should just use frameworks and implement business logic- while using CS background to fully understand frameworks already existing.
> while using CS background to fully understand frameworks already existing.
Most frameworks today are so complicated that you typically cannot understand them fully, and even understanding them somewhat partially is more than a full-time job.
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.
I don’t find them useful in the sense of directly applying practical techniques in my day job, but I consider them somewhat necessary background reading to get into the right state of mind. You can very quickly tell when someone never acquired any academic knowledge in this area (or never played with functional languages or similar pastimes) - you can’t explain to those people why modifying global variables all over the place in a large program is a bad idea and other things like that. They just nod along skeptically and then somehow keep stumbling into the same kind of mess over and over.
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.
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.
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...
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 HTML5 version if you want to read it in a browser, but with nice formatting that the MIT original version: https://sarabander.github.io/sicp/
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)?
It’s a much, much denser successor to sicp. I hadn’t succeeded in self-studying with it despite strong lisp/scheme chops and strong affinity for sicp.
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).
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 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.
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
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.
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.
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 don’t understand this comment. If you master the material you know more than 90% of engineers in the field.
> If you master the material you know more than 90% of engineers in the field.
Telling someone that he/she is smarter than 90% of the people is not a praise. :-)
amen… just look at 90% of people at the DMV :-)
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.
I took cs61a at Berkeley as my very first computer science class I couldn't program I never tried to so scheme was my first language.
My ta told me that everybody should take the class twice when you first come in and when you're graduating.
When you first take it especially if you know other languages like C at the time you don't get the full depth of the problems you're given a great introduction and you think you understand everything but you don't realize the depth of complexity. Message passing the metacircular evaluator, continuations as the basis of all flow control, etc
You think they are neat tricks that you understand the curriculum because you can do the homework you don't understand how those neat tricks are really the basis of everything else you'll do.
When you're graduating you've had time to go through all your classes you realize just how foundation was principles are and you get so much more out of the book.
Well I didn't take the class a second time I need help grade and TA for a couple semesters.
I work as a quant developer and in trading now and even though my field has nothing to do with that I still think it's the basis of me as a developer.
My same experience. For much of the rest of the cs curriculum I felt like we had already to some extent covered the main ideas in 61a with sicp.
i'd also recommend "Concrete Abstractions: An Introduction to Computer Science using Scheme" by Max Hailperin, Barbara Keiser, Karl Knight.
http://www.gustavus.edu/+max/concrete-abstractions.html
I concur, I am learning from it now…
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 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!
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”.
I disagree since the book is using a functional programming language to advance the idea that CS is about procedural epistemology as opposed to the declarative stance of maths.
The idea that a 'procedural programming paradigm' exists in contrast with a 'functional programming paradigm' is blogspeak imho.
Programming Pearls is another book that rereads well. It's also short, too, which makes rereading it possible.
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).
My favourite part of SICP and something that has stuck with me for years is the idea of "wishful programming". That is where you build something top-down by simply wishing you had the lower-level routines. Then, of course, you actually go and build those lower-level routines until you reach the bottom. I find this way of thinking works really well with test-driven development. Write a test against functionality you wish you had, then go and fulfill that wish. Most developers seem to build stuff bottom-up and then end up with something that isn't really what anyone wished for.
> 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.
> 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...
> They stopped teaching computer science and became a vocational school for the tech industry.
Sheldon always said that MIT is a trade school
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.
its watever