Write chapter 3 summary
This commit is contained in:
64
README.md
64
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).
|
Computer Programs](https://mitpress.mit.edu/sites/default/files/sicp/index.html).
|
||||||
I have looked up the answer for some exercises on the
|
I have looked up the answer for some exercises on the
|
||||||
[Scheme Community Wiki](http://community.schemewiki.org/?SICP-Solutions).
|
[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,
|
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
|
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
|
# Chapter 1
|
||||||
@@ -115,4 +116,61 @@ felt a sense of accomplishment when I finished it on my second attempt.
|
|||||||
|
|
||||||
# Chapter 3
|
# 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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user