1 / 52

Midterm & Concept Review

Midterm & Concept Review. CS 510, Fall 2002 David Walker. Midterm. Most people did just fine greater than 90 = exceptional 80-90 = good less than 80 = need more work Three main parts: MaybeML: 35 Objects: 35 Imperative objects: 30. Type-directed Translations.

zanta
Download Presentation

Midterm & Concept Review

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Midterm & Concept Review CS 510, Fall 2002 David Walker

  2. Midterm • Most people did just fine • greater than 90 = exceptional • 80-90 = good • less than 80 = need more work • Three main parts: • MaybeML: 35 • Objects: 35 • Imperative objects: 30

  3. Type-directed Translations • What is a type-directed translation?

  4. Type-directed Translations • What is a type-directed translation? • it is a function (a compiler) that takes a typing derivation for a source-language expression and produces a target-language expression • we can define type-directed translations using judgments: (G |- e : t) ==> e’ • e is a source term; e’ is a target term • we define the translation using inference rules. eg: (G |- e1 : t1 -> t2) ==> e1’ (G |- e2 : t1) ==> e2’ ------------------------------------------------------------------- (G |- e1 e2 : t2) ==> e1’ e2’

  5. Type-preserving Translations • When is a translation is type-preserving?

  6. Type-preserving Translations • When is a translation is type-preserving? • If given a valid derivation, it produces a well-typed target expression • We often prove a theorem like this: • if (G |- e : t) ==> e’ then Trans(G) |- e’ : Trans(t) • where Trans(t) is a type translation function this is an ordinary typing judgment in the target language

  7. Maybe ML • Syntax: • t ::= Bool? | t1 ?-> t2 • e ::= x | true | false | null | if e1 then e2 else e3 | if? e1 then e2 else e3 | fun f (x:t1) : t2 = e | e1 e2

  8. MinML (unit,+,->,exn) • Syntax: • t ::= unit | t1 + t2 | t1 -> t2 • e ::= x | () | e1; e2 | inl (t,e1) | inr (t,e2) | ... • Question: • Define a type-directed, type-preserving translation from MaybeML to MinML

  9. Type Translation • What I expected: • Trans (Bool?) = unit + (unit + unit) • Trans (t1 ?-> t2) = unit + (Trans(t1) + Trans(t2)) • Another possibility: • Trans (Bool?) = unit + (unit + unit) • Trans (t1 ?-> t2) = t1 -> t2

  10. Type Translation • Almost: • Trans (Bool?) = anyt • Trans (t1 ?-> t2) = anyt where anyt = unit + (unit + unit) + (anyt -> anyt) • what is wrong here?

  11. Type Translation • Almost: • Trans (Bool?) = anyt • Trans (t1 ?-> t2) = anyt where anyt = unit + (unit + unit) + (anyt -> anyt) • what is wrong here? Need a recursive type: • anyt = rec a. unit + (unit + unit) + (a -> a)

  12. Term Translation • Mirrors the form of the static semantics • Uses judgments with the form: • (G |- e1 : t) ==> e1’ • Invariant: • If (G |- e1 : t) ==> e1’ then Trans(G) |- e1’ : Trans(t) Key: e1’ must type check under fully translated environment

  13. Term Translation (no opt.) • Example: • Example: --------------------------------------------------------------------------- (G |- true : Bool?) ==> inr (Trans(Bool?), inl (unit + unit, ())) (G |- e1 : t1 ?-> t2) ==> e1’ (G |- e2 : t1) ==> e2’ (x,y not in Dom(G)) --------------------------------------------------------------------------- (G |- e1 e2 : t2) ==> case e1’ of ( inl (x) => fail | inr (y) => y e2’)

  14. Term Translation (no opt.) • Wrong (but it was pretty tricky, so don’t worry): (G,f : t1 ?-> t2, x : t1 |- e : t2) ==> e’ ------------------------------------------------ (G |- fun f (x : t1) : t2 = e ==> inr (..., fun f (x : Trans(t1)) : Trans(t2) = e’)

  15. What goes wrong? • Consider: fun f (x : unit) : unit = f x • and its translation: inr (..., fun f (x : unit) : unit = case f of ( inl (y) => fail | inr (z) => z x)) this is a function NOT a sum value

  16. Term Translation (no opt.) • The point of doing a proof is to discover mistakes! • Must prove result of trans has the right type: ------------------------------------------------------ (by IH) G,f : T(t1) -> T(t2), x : T(t1) |- e’ : T(t2) ------------------------------------------------------------------ (fun) Trans(G) |- fun f (x : T(t1)) : T(t2) = e’ : T(t1) -> T(t2) ------------------------------------------------------------------ (inr) Trans(G) |- inr (..., ....) : unit + (T(t1) -> T(t2))

  17. Term Translation (no opt.) • We can’t apply the induction hypothesis! • (T(G) |- e : t) ==> e’ is necessary not the translation of a function type (unit + T(t1) -> T(t2)) ------------------------------------------------------ (by IH) G,f : T(t1) -> T(t2), x : T(t1) |- e’ : T(t2) ------------------------------------------------------------------ (fun) Trans(G) |- fun f (x : T(t1)) : T(t2) = e’ : T(t1) -> T(t2) ------------------------------------------------------------------ (inr) Trans(G) |- inr (..., ....) : unit + (T(t1) -> T(t2))

  18. Term Translation (no opt.) • How do we fix this? • create something with type (unit + T(t1) -> T(t2)) to use inside the function • then bind that something to a variable f for use inside e’ • our old translation gave us something with the type T(t1) -> T(t2) ...

  19. Term Translation (no opt.) • How do we fix this? (G,f : t1 ?-> t2, x : t1 |- e : t2) ==> e’ ------------------------------------------------ (G |- fun f (x : t1) : t2 = e ==> inr (..., fun f (x : Trans(t1)) : Trans(t2) = let f = inr (..., f) in e’) where let x = e1 in e2 is ((fun _ (x : ...) : ... = e2) e1)

  20. A useful fact • A let expression is normally just “syntactic sugar” for a function application • let x = e1 in e2 is the same as • (fn x => e2) e1

  21. Optimization • Observation: • There are only a couple of null checks that appear in our translation. • Can we really do substantially better?

  22. Optimization • Observation: • There are only a couple of null checks that appear in our translation. • Can we really do substantially better? • YES! • The expressions that result from the translation have many, many, many null checks: • if true then if false then if true then .... our translation inserts 3 unnecessary null checks!

  23. Some Possibilities • Some people defined a few special-case rules: • Detect cases where values are directly elimiated and avoid null checks: • (fun f (x:t1) :t2 = e) e’ translated differently • if true then e1 else e2 translated differently • Others: • if? x then (if? x then e1 else e2) else e3 • These people received some marks

  24. A Much More General Solution • Do lazy injections into the sum type • Keep track of whether or not you have done the injection using the type of the result expression • if t’ = (unit + unit) or (trans(t1) -> trans(t2)) then you haven’t injected the expression e’ into a sum yet • you can leave off unnecessary injections around any expression, not just values (G |- e : t) ==> (e’ : t’)

  25. A Much More General Solution • New rules for introduction forms: • Extra rules for elimination forms: ---------------------------------------------------------- (G |- true : Bool?) ==> (inr (..., ()): unit + unit) (G |- e1 : Bool? ==> (e1’, t) t notnull (G |- e2 : ts ==> (e2’, t2’) (G |- e3 : ts ==> (e3’, t3’) e2’,e3’,t2’,t3’ unifies to e2’’,e3’’,t’’ ---------------------------------------------------------- (G |- if e1 then e2 else e3 : ts) ==> if e1 then e2’’ else e3’’ : t’’

  26. New Judgments • Natural Types: • “Unification” ------------------------ (unit + unit) notnull ---------------------- (t1 -> t2) notnull t2 = t3 ------------------------------------- e2,e3,t2,t3 unifies to e2,e3,t2 t2 = unit + t3 --------------------------------------------- e2,e3,t2,t3 unifies to e2,inr(t2,e3),t2 t3 = unit + t2 --------------------------------------------- e2,e3,t2,t3 unifies to inr(t3,e2),e3,t3

  27. Objects • Most people did well on the definition of the static and dynamic semantics for objects • if you want to know some detail, come see me during my office hours • Less well on the imperative features

  28. Terminology • What is a closed expression?

  29. Terminology • What is a closed expression? • An expression containing no free variables. • ((fun f (x:bool):bool = x x) true) is closed • ((fun f (x:bool):bool = y x) true) is not closed • Mathematically: if FV is a function that computes the set of free variables of an expression then • e is closed if and only if FV(e) = { }

  30. Terminology • What is a well-formed expression?

  31. Terminology • What is a well-formed expression? • An expression that type checks under some type context G. • ((fun f (x:bool):bool = x x) true) is not well formed • ((fun f (x:bool):bool = y x) true) is well-formed in the context G = [y:bool -> bool]

  32. Terminology • What is (e : t) an abbreviation for?

  33. Terminology • What is (e : t) an abbreviation for? • the typing judgment: • . |- e : t • If (e : t) then what else do we know? empty context

  34. Terminology • What is (e : t) an abbreviation for? • the typing judgment: • . |- e : t • If (e : t) then what else do we know? • we know that e contains no free variables • in other words, e is closed • (we might know other things if e also happens to be a value) empty context

  35. Terminology • What is a value?

  36. Terminology • What is a value? • it is an expression that does not need to be further evaluated (and it is not stuck) • How do we normally define values?

  37. Terminology • How do we normally define values? • We declare a new metavariable v and give its form using BNF: v ::= x | n | <v1,v2> | fun f (x : t1) : t2 = e • What is the difference between a metavariable v and an expression variable x? • Alternatively, we define a value judgment: |- v1 value |- v2 value ---------------------------------- |- <v1,v2> value -------------- |- x value -------------- |- n value

  38. Terminology • Does it matter whether we use BNF or a series of judgments to define the syntax of values and expressions?

  39. Terminology • Does it matter whether we use BNF or a series of judgments to define the syntax of values and expressions? • No! BNF is just an abbreviation for the inductive definition that we would give using judgments instead • Why don’t we define typing rules using BNF if it is so darn convenient?

  40. Terminology • Does it matter whether we use BNF or a series of judgments to define the syntax of values and expressions? • No! BNF is just an abbreviation for the inductive definition that we would give using judgments instead • Why don’t we define typing rules using BNF if it is so darn convenient? • Typing rules are context-sensitive. BNF is used for context-insensitive definitions.

  41. Terminology • What is strange about the following sentence? • If (v : t) and v is a closed, well-formed value then the canonical forms lemma can tell us something about the shape of v given the type t.

  42. Terminology • What is strange about the following sentence? • If (v : t) and v is a closed, well-formed value then the canonical forms lemma can tell us something about the shape of v given the type t. • The red part is totally redundant! • If you are using the metavariable v, then you should have already defined it so that it refers to values. • (v : t) should also have been defined before. It should trivially imply that v is closed. It defines what it means for v to be well-formed! • If you write a sentence like this on the final, you might find yourself losing points....

  43. Back to objects • In the future, when I say “write an expression that does ...” you should always write a well-formed, closed expression unless I specify otherwise. {getloop = fn (x). ({loop = fn(y).y.loop} : {loop : t}) } : {getloop : {loop : t} } isn’t really an expression! It contains the metavariable t.

  44. Back to objects {getloop = fn (x). ({loop = fn(y).y.loop} : {loop : { }}) } : {getloop : {loop : { }} } is what you want to do.

  45. Imperative objects • Syntax • t ::= {l = t,...} • e ::= x | {l = b,...} | e.l | e.l <- b | ... • b ::= fn(x).e

  46. Operational semantics • Without imperative features (field update) we can use the ordinary M-machine definitions e -> e’

  47. Operational semantics • The obvious M-machine definition for object update doesn’t work: e = {lk = b’,l’’ = b’’...} ----------------------------------------- (e.lk <- b) -> {lk = b,l’’ = b’’...}

  48. Operational semantics this update only has local effect • Here’s why: let x = {n = fn(_).3} in let _ = (x.n <- fn(_).2) in x.n let _ = ({n = fn(_).3}.n <- fn(_).2) in {n = fn(_).3}.n let _ = {n = fn(_).2} in {n = fn(_).3}.n {n = fn(_).3}.n 3

  49. Operational semantics • We need to augment our operational semantics with a global store. • A store S is a finite partial map from locations (r) to values. • (what is a finite partial map?) • v ::= {l=b,...} | r • run-time expressions include locations r • Our semantics now has form: • (S,e) -> (S’,e’)

  50. Operational semantics • Rules: ------------------------------------------------ (S, {l = b,...}) -> (S[r -> {l = b,...}], r) S(r) = {l = fn(x).e,...} ----------------------------- (S, r.l) -> (S, e[S(r)/x]) S(r) = {l = b’’, l’ = b’,...} ------------------------------------------------------- (S, r.l <- b) -> (S[r -> {l = b, l’ = b’,...}], r)

More Related