Essentials of Programming Languages
State & References
"Features" so far
Categories of Values so far
Effects
exp
value
effects
eval
both
What is an effect?
Modeling State
store :: loc -> val�
Operations
Implementation depends on meta-language.
Scala: Use a map.
Language extension (explicit refs)
e ::= ... | new e | deref e
| setref e e
Exp = ... | New Exp | Deref Exp
| Setref Exp Exp
Val = ... | VLoc Loc
Example
let x = new 1 in
let y = x in // location assignment
if deref x = deref y then // val comp.
setref x 2
else
setref y 7
(deref x) + (deref y)
eval(...) = 4
Categories of Values
Consequences: Global change
let x = 5 in
...
Can change behavior everywhere
Consequences: We lose purity
eval(f 42) = 10
Order of execution is suddenly important!
Order of execution
(f e1 (f e2 e3))
(f e1 (f e2 e3))
Evaluation (1)
eval :: exp -> env -> val
eval' :: exp -> env ->
store -> (store, val)
Evaluation (2) - Order important!
Change all calls from eval to eval'.
eval (Add e1 e2) env =
VNum (getNum (eval e1 env)
+ getNum (eval e2 env))
eval' (Add e1 e2) env store =
let (store',v1) = eval' e1 env store in
let (store'',v2) = eval' e2 env store' in
let res = VNum (getNum v1 + getNum v2) in
(store'', res)
Evaluation (3)
eval' (VLoc i) env store = (store, VLoc i)
eval' (New e) env store =
let (store',v) = eval' e env store in
let (store'',l) = insert store' v in
(store'', VLoc l)
Evaluation (4)
eval' (Deref e) env store =
let (store',VLoc loc) = eval' e env store in
(store',fetch store' loc)
eval' (Setref e e') env store =
let (store',VLoc loc) = eval' e env store in
let (store'',v) = eval' e' env store' in
(update store'' l v, v)
Refs and functions
Functions integrate without problems
let incValue = new
fun a =>
let v = deref a in
setref a (v + 1)
let _ = setref incValue (fun a => a) in
let x = new 5 in
(deref incValue) x
Can we get rid of deref, ref, setref?
Example
Explicit:
let x = new 1 in
let _ = setref x 5
deref x
Implicit:
let x = 1 in
x := 5;
x
Language extension (implicit refs)
e ::= ... | x := e | e;e
Exp = ... | Assign Var Exp
| Seq Exp Exp
Val = ... | VLoc Loc
Removed:
Evaluation (1)
Change signature of Environment:
put :: Map Ident Loc -> Ident -> Loc
-> Map Ident Loc
get :: Map Ident Loc -> Ident -> Loc
eval' (Let x e body) env store =
let (store',v) = eval' e env store in
let (store'', loc) = insert store' v
let env' = put env x loc in
eval' body env' store''
Evaluation (2)
eval' (Assign id e) env store =
let (store',v) = eval' e env store in
let loc = get env id in
(update store' loc v,v)
Evaluation (3)
eval' (Seq e1 e2) env store =
let (store',_) = eval' e1 env store in
eval' e2 env store'
Evaluation (4)
eval' (Var x) env store =
let loc = get env x in
(store, fetch store loc)
Explicit vs. implicit refs
You know any other language with explicit refs?
Categories of Value
Consequences
fun x => x := 5
Function calls with implicit refs
fun x => x := 5
Example
let x = 1 in
let addOne = fun a => x + a in
// ...
x := 11;
// ...
addOne 4
Call-by-* strategies
So far, we had:
New:
Call-by-reference
eval' (App e1 e2) env store =
let (store', VClos x env' body) =
eval' e1 env store in
let (store'', arg) =
match e2 with
Var x => (store', get env x)
_ => let (store''', v) =
eval' arg env store' in
insert store''' v
in
eval' body env' store''
Call-by-need
General concept:
Thunk exp env
Deallocation
Language extension (Manual free)
e ::= ... | free e
Exp = ... | Free Exp
New operation on store:
delete :: store -> loc -> store
Evaluation
eval' (Free exp) env st =
let (st',VLoc loc) = eval' exp env st in
(delete st' v, v)
Problems
What if a cell is still referenced after free?
x := 5;
free x;
x
Garbage collection
Idea: