diff --git a/README.md b/README.md index a137b7c..2835341 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ These are my solutions to the CS classic [Structure and Interpretation of Computer Programs](https://mitpress.mit.edu/sites/default/files/sicp/index.html). I have looked up the answer for some exercises on the [Scheme Community Wiki](http://community.schemewiki.org/?SICP-Solutions). -Such exercise have a mark in their respective script. +I have marked such exercises in their respective script. You can use the Scheme implementation by the MIT to run these scripts. In Arch, execute `pacman -S mit-scheme` to install it. Then run the scripts via -`mit-scheme --quiet < script.scm`. +`mit-scheme --quiet < script.scm`. You can also use the shell script `./run +script.scm`. -**This is currently (2021/01/25) work in progress.** +**This is currently (2021/05/13) work in progress.** # Chapter 1 @@ -115,4 +116,61 @@ felt a sense of accomplishment when I finished it on my second attempt. # Chapter 3 +Chapter 3 introduces statefulness into the computation model. I want to point +out how far we have come without explaining variables. It is one of the reasons +why I enjoyed the book so much. Even though I was already familiar with +functional programming, the book taught me how to think purely, leading to more +solid code. + +The initial section shows how we can use message dispatching to maintain the +balance of a bank account. The general idea is to define variables within the +scope of a procedure. Any procedure defined in the same context has access to +these variables. By returning a procedure, we can thus manage the variables, +such as the bank account balances, after leaving the original context. + +For this approach, the interpreter needs to know how to resolve variables in a +specific context. The book introduces the environment model of computation to +handle variables within different contexts. As we would expect from an +imperative programming language, there are nested frames, and the interpreter +looks up variables starting from the current frame going outwards. + +Based on our new understanding of statefulness, we learn about mutable data +structures such as queues and tables. By implementing some of these data +structures in Scheme, I understood and appreciated them more deeply. + +The chapter about mutable data structures finishes with a simulator for digital +circuits and a constraint solver. That is probably the only part in the book +where I had wished that there were more exercises. There are some exercises for +both tools, but they don't go too deep. + +Of course, once we have introduced statefulness, that opens the possibility for +race conditions when multiple parts of the program access variables +concurrently. The book explains nicely how transfers from different bank +accounts yield different results depending on the execution order. We can use +resources to manage concurrent accesses, but that can lead to additional +problems like deadlocks. The book explains all of that beautifully within a +single section. + +Lastly, we learn about the stream model for computation. Streams are delayed +lists which means that the interpreter computes the cdr-arguments on demand. +This paradigm allows us to reimplement a couple of procedures arguably more +elegantly. Just take a look at the beautiful implementation of the Fibonacci +sequence. + +```scheme +(define fibs + (cons-stream 0 + (cons-stream 1 + (add-streams (stream-cdr fibs) + fibs)))) +``` + +The chapter ends by explaining how the stream paradigm can resolve the +concurrency problem, at least partially. We can use streams to represent events +that happen over time. Nevertheless, if we get streams from multiple sources, +it's still unclear how to merge them deterministically. The final sentiment has +changed much in the last thirty years. Concurrency is still a challenge, for +example, in embedded development. + +# Chapter 4