Btw, I've just read the first section of Chapter 5 [Computing with Register Machines] for the first time, and think it's the best introduction to assembly that I've seen (and I've seen a few).
Calling it 'fake' is dismissive. Also, it isn't written in Scheme, but merely described in the native data format: lists of symbols.
The next section builds a virtual machine that is written in Scheme to run the code. One of the beauties of Scheme/Lisp (and source of much of its power) is the simplicity of the syntax. It allows it to be incredibly succinct.
The last section in the chapter builds a compiler to translate Scheme into this virtual machine assembly code so you can run it in the virtual machine simulator. An ouroboros.
I can see how 6.001 was a bit like jumping into the deep end to learn to swim.
Starting from, "To design a register machine, we must design its data paths (registers and operations) and the controller that sequences these operations." In less than 5,000 words it proceeds to implementing recursive procedure calls in what amounts to assembly:
(controller
(assign continue (label fact-done)) ; set up final return address
fact-loop
(test (op =) (reg n) (const 1))
(branch (label base-case))
(save continue) ; Set up for the recursive call
(save n) ; by saving n and continue.
(assign n (op -) (reg n) (const 1)) ; Set up continue so that the
(assign continue (label after-fact)) ; computation will continue
(goto (label fact-loop)) ; at after-fact when the
after-fact ; subroutine returns.
(restore n)
(restore continue)
(assign val (op *) (reg n) (reg val)) ; val now contains n(n - 1)!
(goto (reg continue)) ; return to caller
base-case
(assign val (const 1)) ; base case: 1! = 1
(goto (reg continue)) ; return to caller
fact-done)
A translation of:
(define (factorial n)
(if (= n 1)
1
(* (factorial (- n 1)) n)))
It's quite a jump in knowledge, but explained very clearly through a series of guided examples. It's close to equivalent code in x86 or arm, but much easier to read.
well it's really very hard to find the worst idea because there are so many bad ideas in programming languages. of course the ones that bother me the most are the ones that are designed to keep me from doing what i want. i was after all a libertarian programmer. okay. and so i don't want anybody to tread on me, but the worst features of languages that i can think of -- the really worst thing -- is complex syntax. okay. and as alan perlis quipped, syntactic sugar
yields cancer of the semicolon. okay. the problem with complex syntax is that it hides possibly important to understand mechanisms, but more importantly it makes it very difficult to write programs that manipulate programs -- that read them, that write them and analyze them. and that, in fact, i often have programs that write programs that i want to run in-line. for example, numerical programs that are constructed from symbolic algebra expressions. okay. so that's a nice feature of lisp, for example, which has lots of parentheses, is a uniform representation of programs as data and the ability to execute code that you've just constructed. and as a consequence i would say my mantra here is syntax without representation is tyranny.
Calling it 'fake' is dismissive. Also, it isn't written in Scheme, but merely described in the native data format: lists of symbols.
The next section builds a virtual machine that is written in Scheme to run the code. One of the beauties of Scheme/Lisp (and source of much of its power) is the simplicity of the syntax. It allows it to be incredibly succinct.
The last section in the chapter builds a compiler to translate Scheme into this virtual machine assembly code so you can run it in the virtual machine simulator. An ouroboros.
SICP is a gem. Thank you Hal and Gerry!