Evaluation by Rewriting One very nice feature of pure functional languages is that we can explain their behavior (semantics) by means of simple rewriting rules based on substi- tution. We view evaluation as a sequence of transformations on the program text. We begin with the original source program. At each evaluation step, the pro- gram is rewritten to a new form, hopefully smaller and simpler than before. Execution is completed when the program reaches a particularly simple normal form, such as con- stants, constructed data values, and functions. We call these values (v). Here are some suitable rules for pure, non-recursive Standard ML expressions (e). Remember, SML uses eager (or "call-by-value") semantics. e1 [ e2 / x ] means e1 with e2 substituted for vari- able x Examples: (p + q) [ 10 / q ] j (p + 10) (p + q) [ q / p ] j (q + q) (p + q) [ (r + 32) / q ] j (p + (r + 32)) Rules (1) let val x = v in e end ; e [ v / x ] (2) If e1 ; e01 then let val x = e1 in e2 end ; let val x = e01 in e2 end (3) if true then e1 else e2 ; e1 (4) if false then e1 else e2 ; e2 (5) If e0 ; e00 then if e0 then e1 else e2 ; if e00 then e1 else e2 (6) (fn x => e) v ; e [ v / x ] (7) If e1 ; e01 then e1 e2 ; e01 e2 (8) If e2 ; e02 then v1 e2 ; v1 e02 (9) v1 primop v2 ; result of performing primop on v1, v2 (10) If e1 ; e01 then e1 primop e2 ; e01 primop e2 (11) If e2 ; e02 then v1 primop e2 ; v1 primop e02 Evaluation by Rewriting - Example let fun f x = if x < 0 then 0 else x in let val p = f 2 in f (p - 3) end end j let val f = fn x => if x < 0 then 0 else x in let val p = f 2 in f (p - 3) end end ;1 let val p = (fn x => if x < 0 then 0 else x) 2 in (fn x => if x < 0 then 0 else x) (p - 3) end ;2;6 let val p = if 2 < 0 then 0 else 2 in (fn x => if x < 0 then 0 else x) (p - 3) end ;2;5;9 let val p = if false then 0 else 2 in (fn x => if x < 0 then 0 else x) (p - 3) end Example - continued ;2;4 let val p = 2 in (fn x => if x < 0 then 0 else x) (p - 3) end ;1 (fn x => if x < 0 then 0 else x) (2 - 3) ;8;9 (fn x => if x < 0 then 0 else x) ("1) ;6 if "1 < 0 then 0 else "1 ;5;9 if true then 0 else "1 ;3 0 Substitition Revisited The correct definition of substitution is a little tricky. Basic idea: only substitute for free variables, i.e., those not redefined by a let or fn binding. let val a = 10 in let val b = a+10 in let val a = b+20 in a+30 end end ;1 let val b = 10+10 in let val a = b+20 in a+30 end end ; ; 70 NOT ;1 let val b = 10+10 in let val a = b+20 in 10+30 end end ; ; 40