Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: