But I had forgotten many of the details. Here is just one: in 3.1.1, Local State Variables, SICP shows how to, in effect, define classes and create objects using only function definition with lambda and set! (that is, assignment) in the definition body. The function you define this way is a like a class, the functions it returns are like instances. So you can do all this without any specifically object-oriented language features. This occupies just a few pages near the beginning of a long book - the whole book is dense with worked-out ideas like this.
I would add that the cumulative effect of all these examples in SICP is to demonstrate that you can solve any programming problem from first principles - that is, by combining a few simple but powerful constructs in the several ways they describe. Moreover, a solution constructed this way might be simpler and easier to understand than a solution made the more usual way: by looking for a specialized language construct or library that seems to offer an already-made solution to the problem.
(This is copied from a comment I made here several years ago: https://news.ycombinator.com/item?id=8495934)