Title: Abstract Machines
1Abstract Machines
- COS 441
- Princeton University
- Fall 2004
2A More Abstract View of Stacks
- Mitchells account of functions, scope, and
storage management is a very low-level
implementation orientated view of programming
language - Harper presents a more abstract view of many of
the same ideas using a more formal approach
3The M-machine and C-Machine
- We start with the SOS for MinML and progressively
refine the semantics to a more low-level model - M-machine repeatedly searches for a subterm that
can be evaluated in one primitive step - C-machine keeps track of subterms that need to be
reduce with a stack of frames
4Very Simplified Examples
- We will workout an M, C, and C with return for
this very simple language
Numbers n 2 N
Expressions e n (e1,e2)
Values v n
5M-Machine Evaluation
- ((1,2),(3,4))
- ?M (3,(3,4)) A2 with A1
- ?M (3,7) A3 with A1
- ?M 10 A1
6Stacks and Frames
7Stacks and Frames
Stacks k ² f B k
Frames f (v1,) (,e2)
8Stacks and Frames
Stacks k ² f B k
Frames f (v1,) (,e2)
- Stack is just a sequence of frames the B operator
pushes a frame on to a stack - A frame is an expression with a hole
- Holes are where values will be placed when we
pop the frame from the stack
9Step Relation for the C-machine
10Step Relation for the C-machine
Push a frame and evaluate e1
11Step Relation for the C-machine
Push a frame and evaluate e1
- Continue evaluation of e2
12Step Relation for the C-machine
Push a frame and evaluate e1
- Continue evaluation of e2
Return evaluation
13Example Evaluation
- (²,((1,2),(3,4)))
- ?C ((,(3,4)) B ²,(1,2)) push
- ?C ((,2) B(,(3,4)) B ²,1) push
- ?C ((1,) B(,(3,4)) B ²,2) continue
- ?C ((,(3,4)) B ²,3) return
- ?C ((3,) B ²,(3,4)) continue
- ?C ((,4) B (3,) B ²,3) push
- ?C ((3,) B (3,) B ²,4) continue
- ?C ((3,) B ²,7) return
- ?C (²,10) return
14C-Machine vs M-Machine
- C-Machine has an explicit stack
- Closer to lower-level machine implementation
- M-Machine hide stacks in premises
- Easier for proof of type soundness
- Relation to C and M machines
- Must defined a hole filling relation that
converts a C machine state into a closed
expression - We can show
15C and M-Machine States
- (1,) B(,(3,4)) B ² _at_ 2
- (,(3,4)) B ² _at_ (1,2)
- ² _at_ ((1,2),(3,4))
16Example Evaluation
- (²,((1,2),(3,4))) ((1,2),(3,4))
- ?C ((,(3,4)) B ²,(1,2)) ((1,2),(3,4))
- ?C ((,2) B(,(3,4)) B ²,1)
((1,2),(3,4)) - ?C ((1,) B(,(3,4)) B ²,2)
((1,2),(3,4)) - ?C ((,(3,4)) B ²,3) (3,(3,4))
- ?C ((3,) B ²,(3,4)) (3,(3,4))
- ?C ((,4) B (3,) B ²,3) (3,(3,4))
- ?C ((3,) B (3,) B ²,4) (3,(3,4))
- ?C ((3,) B ²,7) (3,7)
- ?C (²,10) 10
17Formal Relationship
- From the above we have (²,e)
?C (²,v) iff e ?M v
18Intuition Behind Proof
- Theorem if (²,e) ?C (²,v) then e ?M v
- If we have
- (²,e) ?C S1?C S2 ?C Sn ?C (²,v)
- we can replace the first few C steps with one M
step so that - e ?M e and (²,e) ?C Sn ?C (²,v)
- until we have e ?M v
19Intuition Behind Proof
- Theorem if e ?M v then (²,e) ?C (²,v)
- If we have
- e ?M e1 ?M en-1 ?M en ?M v
- we can replace the last M step with some C
steps so that - e ?M en-1 and (²,en) ?C (²,v)
- until we have (²,e) ?C (²,v)
20Modified C-Machine
- Before we talk about the E-Machine
- Modify the C-Machine in a small way to make
return of values more explicit with new state
(v,k)
(k,(e1,e2)) ?C ((,e2)Bk,e1) push
(k,v) ?C (v,k) return
(n2,(n1,)Bk) ?C (n1 n2,k) pop
(v1,(,e2)Bk) ?C ((v1,)Bk,e2) continue
21Example Evaluation
- (²,((1,2),3))
- ?C ((,3) B ²,(1,2)) push
- ?C ((,2) B(,3) B ²,1) push
- ?C (1,(,2) B(,3) B ²) return
- ?C ((1,) B(,3)) B ²,2) continue
- ?C (2,(1,) B(,3) B ²) return
- ?C (3,(,3) B ²) pop
- ?C ((3,) B ²,3) continue
- ?C (3,(3,) B ²) return
- ?C (6,²) pop
22Environments vs. Substitution
- M and C machine use substitution to replace bound
occurrence of a variable with a value - Substitution is an inefficient approach in
realistic implementations - We can use environment semantics instead to avoid
substitution - Study this in a big-step semantics first for
clarity
23Substitution Semantics
Names x 2
Nums n 2 N
Exprs e numn plus(e1,e2) times(e1,e2)
let(e1,x.e2) x
Vals v numn
24Environment Semantics
Names x 2
? ? ? ?
Vals v numn
Envs Env x1? v1, , xn ? vn
Progs Prg (Env,e)
25Dynamic Scoping
- Values of arithmetic expressions do not contain
any variables - What about ?-calculus semantics?
- Naïve/incorrect environment semantics for
?-calculus leads to dynamic scoping - Original scoping rules for LISP
- Easy to implement in an interpreter hard for
compiler - Still lives on in emacs LISP, TCL provides
controlled version via upvar, limited form of
dynamic scoping in Python, Mathmatica Block and
S-plus)
26Dynamic Scoping
Names x 2
Exprs e lam(x.e) apply(e1,e2) x
Vals v lam(x.e)
Envs Env x1? v1, , xn ? vn
Progs Prg (Env,e)
- Similar to simple arithmetic language
- Values are subset of expressions
27Dynamic Scoping
Vals v lam(x.e)
Envs Env x1? v1, , xn ? vn
Progs Prg (Env,e)
28Example Dynamic Scoping
- Evaluates function body in calling environment
- Allows capturing of unbound variables in
expressions
(,(?f.((?y.f 0) 1)) (?x.y)) ? ??
29Example Dynamic Scoping
(,?f.((?y.f 0) 1)) ? (?f.((?y.f 0)
1)) (,(?x.y)) ? (?x.y) (f?(?x.y),(?y.f 0) 1)
? ??
- (,(?f.((?y.f 0) 1)) (?x.y)) ? ??
30Example Dynamic Scoping
(f?(?x.y),(?y.f 0)) ? (?y.f 0) (f?(?x.y),1) ?
1 (f?(?x.y),y?1,f 0) ? ??
- (f?(?x.y),(?y.f 0) 1) ? ??
31Example Dynamic Scoping
(f?(?x.y),y?1,f) ? (?x.y) (f?(?x.y),y?1,0) ?
0 (f?(?x.y),y?1,(?x.y) 0) ? ??
32Example Dynamic Scoping
(f?(?x.y),y?1,(?x.y)) ? (?x.y) (f?(?x.y),y?1,0
) ? 0 (f?(?x.y),y?1,x?0,y) ? ??
- (f?(?x.y),y?1,(?x.y) 0) ? ??
33Example Dynamic Scoping
(f?(?x.y),y?1,(?x.y)) ? (?x.y) (f?(?x.y),y?1,0
) ? 0 (f?(?x.y),y?1,x?0,y) ? 1
- (f?(?x.y),y?1,(?x.y) 0) ? 1
34Example Dynamic Scoping
(f?(?x.y),y?1,f 0) ? (?x.y) (f?(?x.y),y?1,0)
? 0 (f?(?x.y),y?1,(?x.y) 0) ? ??
35Dynamic Scope
- Many languages seem to support dynamic scope
because it is easy to implement - Is dynamic scoping a broken or useful
feature? - Trend seems to be against dynamic scope
- However, lets illustrate why dynamic scope can be
useful - Will use TCL and ELISP as examples