[Concrete Syntax] Program ::= Expression Expression ::= ... | proc (Identifier) Expression | (Expression Expression)
[Abstract Syntax] Program ::= a-program (exp) Expression ::= ... | proc-exp (var body) // var: formal parameter | call-exp (rator rand)
(value-of (proc-exp 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦) ρ) = ?
def inc(x): return x + 1 x = inc print(x)
<function inc at 0x7f8b3c7b7d30>
(num-val 3) (num-val 10) (bool-val #t) (bool-val #f)
(value-of (proc-exp 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦) ρ) = (proc-val (procedure 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦))
let x = 200 in let f = proc (z) -(z,x) in let x = 100 in let g = proc (z) -(z,x) in -((f 1),(g 1))
(value-of (proc-exp 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦) ρ) = (proc-val (procedure 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦 ρ))
(value-of 𝑟𝑎𝑡𝑜𝑟 ρ₁) = (proc-val (procedure 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦 ρ₂)) (value-of 𝑟𝑎𝑛𝑑 ρ₁) = 𝑣𝑎𝑙 ---------------------------------------------------------------- (value-of (call-exp 𝑟𝑎𝑡𝑜𝑟 𝑟𝑎𝑛𝑑) ρ₁) = (value-of 𝑏𝑜𝑑𝑦 [𝑣𝑎𝑟=𝑣𝑎𝑙]ρ₂)
(value-of << let x = 200 in let f = proc (z) -(z,x) in let x = 100 in let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₁) = (value-of << let f = proc (z) -(z,x) in let x = 100 in let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₂)
(value-of << let f = proc (z) -(z,x) in let x = 100 in let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₂) = (value-of << let x = 100 in let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₃)
(value-of << let x = 100 in let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₃) = (value-of << let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₄)
(value-of << let g = proc (z) -(z,x) in -((f 1),(g 1)) >> ρ₄) = (value-of << -((f 1),(g 1)) >> ρ₅)
(value-of << -((f 1),(g 1)) >> ρ₅) = (num-val (- (exp-val->num (value-of <<(f 1)>> ρ₅)) (exp-val->num (value-of <<(g 1)>> ρ₅))))
(value-of <<(f 1)>> ρ₅) = (value-of <<(-(z,x))>> [z=1]ρ₂)
(value-of <<(f 1)>> ρ₅) = (value-of <<(-(z,x))>> [z=1]ρ₂) = (num-val -199)
(value-of << -((f 1),(g 1)) >> ρ₅) = (num-val (- (exp-val->num (value-of <<(f 1)>> ρ₅)) (exp-val->num (value-of <<(g 1)>> ρ₅)))) = (num-val (- (exp-val->num (num-val -199)) (exp-val->num (value-of <<(g 1)>> ρ₅))))
(value-of <<(g 1)>> ρ₅) = (value-of <<-(z,x)>> [z=1]ρ₄)
(value-of <<(g 1)>> ρ₅) = (value-of <<-(z,x)>> [z=1]ρ₄) = (num-val -99)
(num-val (- (exp-val->num (num-val -199)) (exp-val->num (value-of <<(g 1)>> ρ₅)))) = (num-val (- (exp-val->num (num-val -199)) (exp-val->num (num-val -99))))
(num-val (- (exp-val->num (num-val -199)) (exp-val->num (value-of <<(g 1)>> ρ₅)))) = (num-val (- (exp-val->num (num-val -199)) (exp-val->num (num-val -99)))) = (num-val -100)
(define-datatype proc proc? (procedure (var identifier?) (body expression?) (saved-env environment?))) (define-datatype expval expval? (num-val (num number?)) (bool-val (bool boolean?)) (proc-val (proc proc?)))
(define value-of (lambda (exp env) (cases expression exp ... (proc-exp (var body) (proc-val (procedure var body env))))))
(define apply-procedure (lambda (proc1 val) (cases proc proc1 (procedure (var body saved-env) (value-of body (extend-env var val saved-env))))))
(define value-of (lambda (exp env) (cases expression exp ... (call-exp (rator rand) (let ((proc (expval->proc (value-of rator env))) (arg (value-of rand env))) (apply-procedure proc arg))))))
(procedure 𝑣𝑎𝑟 𝑏𝑜𝑑𝑦 ρ₂)