Exercise 5.33. Consider the following definition of a factorial procedure, which is slightly different from the one given above: (define (factorial-alt n) (if (= n 1) 1 (* n (factorial-alt (- n 1))))) Compile this procedure and compare the resulting code with that produced for factorial. Explain any differences you find. Does either program execute more efficiently than the other? ———————————————————————————————————————————————————————————————————————— The original: (compile '(define (factorial n) (if (= n 1) 1 (* (factorial (- n 1)) n))) 'val 'next) ((env) (val) ((assign val (op make-compiled-procedure) (label entry2) (reg env)) (goto (label after-lambda1)) entry2 (assign env (op compiled-procedure-env) (reg proc)) (assign env (op extend-environment) (const (n)) (reg argl) (reg env)) (save continue) (save env) (assign proc (op lookup-variable-value) (const =) (reg env)) (assign val (const 1)) (assign argl (op list) (reg val)) (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op cons) (reg val) (reg argl)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch17)) compiled-branch16 (assign continue (label after-call15)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch17 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call15 (restore env) (restore continue) (test (op false?) (reg val)) (branch (label false-branch4)) true-branch5 (assign val (const 1)) (goto (reg continue)) false-branch4 (assign proc (op lookup-variable-value) (const *) (reg env)) (save continue) (save proc) (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op list) (reg val)) (save argl) (assign proc (op lookup-variable-value) (const factorial) (reg env)) (save proc) (assign proc (op lookup-variable-value) (const -) (reg env)) (assign val (const 1)) (assign argl (op list) (reg val)) (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op cons) (reg val) (reg argl)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch8)) compiled-branch7 (assign continue (label after-call6)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch8 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call6 (assign argl (op list) (reg val)) (restore proc) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch11)) compiled-branch10 (assign continue (label after-call9)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch11 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call9 (restore argl) (assign argl (op cons) (reg val) (reg argl)) (restore proc) (restore continue) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch14)) compiled-branch13 (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch14 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (goto (reg continue)) after-call12 after-if3 after-lambda1 (perform (op define-variable!) (const factorial) (reg val) (reg env)) (assign val (const ok)))) The alternate: (compile '(define (factorial-alt n) (if (= n 1) 1 (* n (factorial-alt (- n 1))))) 'val 'next) ((env) (val) ((assign val (op make-compiled-procedure) (label entry2) (reg env)) (goto (label after-lambda1)) entry2 (assign env (op compiled-procedure-env) (reg proc)) (assign env (op extend-environment) (const (n)) (reg argl) (reg env)) (save continue) (save env) (assign proc (op lookup-variable-value) (const =) (reg env)) (assign val (const 1)) (assign argl (op list) (reg val)) (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op cons) (reg val) (reg argl)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch17)) compiled-branch16 (assign continue (label after-call15)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch17 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call15 (restore env) (restore continue) (test (op false?) (reg val)) (branch (label false-branch4)) true-branch5 (assign val (const 1)) (goto (reg continue)) false-branch4 (assign proc (op lookup-variable-value) (const *) (reg env)) (save continue) (save proc) (save env) (assign proc (op lookup-variable-value) (const factorial-alt) (reg env)) (save proc) (assign proc (op lookup-variable-value) (const -) (reg env)) (assign val (const 1)) (assign argl (op list) (reg val)) (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op cons) (reg val) (reg argl)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch8)) compiled-branch7 (assign continue (label after-call6)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch8 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call6 (assign argl (op list) (reg val)) (restore proc) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch11)) compiled-branch10 (assign continue (label after-call9)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch11 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call9 (assign argl (op list) (reg val)) (restore env) (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op cons) (reg val) (reg argl)) (restore proc) (restore continue) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch14)) compiled-branch13 (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch14 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (goto (reg continue)) after-call12 after-if3 after-lambda1 (perform (op define-variable!) (const factorial-alt) (reg val) (reg env)) (assign val (const ok)))) The diff: ((env) ((env) (val) (val) ((assign val (op make-compiled-procedure) ((assign val (op make-compiled-procedure) (label entry2) (label entry2) (reg env)) (reg env)) (goto (label after-lambda1)) entry2 (assign env (op compiled-pr (goto (label after-lambda1)) entry2 (assign env (op compiled-pr (reg proc)) (reg proc)) (assign env (op extend-environment) (assign env (op extend-environment) (const (n)) (const (n)) (reg argl) (reg argl) (reg env)) (reg env)) (save continue) (save continue) (save env) (save env) (assign proc (op lookup-variable-value) (assign proc (op lookup-variable-value) (const =) (const =) (reg env)) (reg env)) (assign val (const 1)) (assign val (const 1)) (assign argl (op list) (assign argl (op list) (reg val)) (reg val)) (assign val (op lookup-variable-value) (assign val (op lookup-variable-value) (const n) (const n) (reg env)) (reg env)) (assign argl (op cons) (assign argl (op cons) (reg val) (reg val) (reg argl)) (reg argl)) (test (op primitive-procedure?) (test (op primitive-procedure?) (reg proc)) (reg proc)) (branch (label primitive-branch17)) compiled-branch16 (assign c (branch (label primitive-branch17)) compiled-branch16 (assign c (assign val (op compiled-procedure-entry) (assign val (op compiled-procedure-entry) (reg proc)) (reg proc)) (goto (reg val)) primitive-branch17 (assign val (op apply-primi (goto (reg val)) primitive-branch17 (assign val (op apply-primi (reg proc) (reg proc) (reg argl)) after-call15 (restore env) (reg argl)) after-call15 (restore env) (restore continue) (restore continue) (test (op false?) (test (op false?) (reg val)) (reg val)) (branch (label false-branch4)) true-branch5 (assign val (const (branch (label false-branch4)) true-branch5 (assign val (const (goto (reg continue)) false-branch4 (assign proc (op lookup-var (goto (reg continue)) false-branch4 (assign proc (op lookup-var (const *) (const *) (reg env)) (reg env)) (save continue) (save continue) (save proc) (save proc) (assign val (op lookup-variable-value) | (save env) (const n) < (reg env)) < (assign argl (op list) < (reg val)) < (save argl) < (assign proc (op lookup-variable-value) (assign proc (op lookup-variable-value) (const factorial) | (const factorial-alt) (reg env)) (reg env)) (save proc) (save proc) (assign proc (op lookup-variable-value) (assign proc (op lookup-variable-value) (const -) (const -) (reg env)) (reg env)) (assign val (const 1)) (assign val (const 1)) (assign argl (op list) (assign argl (op list) (reg val)) (reg val)) (assign val (op lookup-variable-value) (assign val (op lookup-variable-value) (const n) (const n) (reg env)) (reg env)) (assign argl (op cons) (assign argl (op cons) (reg val) (reg val) (reg argl)) (reg argl)) (test (op primitive-procedure?) (test (op primitive-procedure?) (reg proc)) (reg proc)) (branch (label primitive-branch8)) compiled-branch7 (assign con (branch (label primitive-branch8)) compiled-branch7 (assign con (assign val (op compiled-procedure-entry) (assign val (op compiled-procedure-entry) (reg proc)) (reg proc)) (goto (reg val)) primitive-branch8 (assign val (op apply-primit (goto (reg val)) primitive-branch8 (assign val (op apply-primit (reg proc) (reg proc) (reg argl)) after-call6 (assign argl (op list) (reg argl)) after-call6 (assign argl (op list) (reg val)) (reg val)) (restore proc) (restore proc) (test (op primitive-procedure?) (test (op primitive-procedure?) (reg proc)) (reg proc)) (branch (label primitive-branch11)) compiled-branch10 (assign c (branch (label primitive-branch11)) compiled-branch10 (assign c (assign val (op compiled-procedure-entry) (assign val (op compiled-procedure-entry) (reg proc)) (reg proc)) (goto (reg val)) primitive-branch11 (assign val (op apply-primi (goto (reg val)) primitive-branch11 (assign val (op apply-primi (reg proc) (reg proc) (reg argl)) after-call9 (restore argl) | (reg argl)) after-call9 (assign argl (op list) > (reg val)) > (restore env) > (assign val (op lookup-variable-value) > (const n) > (reg env)) (assign argl (op cons) (assign argl (op cons) (reg val) (reg val) (reg argl)) (reg argl)) (restore proc) (restore proc) (restore continue) (restore continue) (test (op primitive-procedure?) (test (op primitive-procedure?) (reg proc)) (reg proc)) (branch (label primitive-branch14)) compiled-branch13 (assign v (branch (label primitive-branch14)) compiled-branch13 (assign v (reg proc)) (reg proc)) (goto (reg val)) primitive-branch14 (assign val (op apply-primi (goto (reg val)) primitive-branch14 (assign val (op apply-primi (reg proc) (reg proc) (reg argl)) (reg argl)) (goto (reg continue)) after-call12 after-if3 after-lambda1 (per (goto (reg continue)) after-call12 after-if3 after-lambda1 (per (const factorial) | (const factorial-alt) (reg val) (reg val) (reg env)) (reg env)) (assign val (const ok)))) (assign val (const ok))))