Download presentation
Presentation is loading. Please wait.
Published byAlexa Beecroft Modified over 9 years ago
1
A Fix for Dynamic Scope Ravi Chugh U. of California, San Diego
2
Backstory 2 Goal: Types for “Dynamic” Languages Core λ-Calculus + Extensions Syntax and Semantics of JavaScript Translation à la Guha et al. (ECOOP 2010)
3
Backstory 3 Goal: Types for “Dynamic” Languages Core λ-Calculus + Extensions Approach: Type Check Desugared Programs Simple Imperative, Recursive Functions are Difficult to Verify
4
4 Translate to statically typed calculus? var fact = function(n) { if (n <= 1) { return 1; } else { return n * fact(n-1); } };
5
let fact = λn. if n <= 1 then 1 else n * fact(n-1) Option 1: λ-Calculus (λ) 5 Translate to statically typed calculus? var fact = function(n) { if (n <= 1) { return 1; } else { return n * fact(n-1); } }; fact is not bound yet… ✗
6
let fact = fix (λfact. λn. if n <= 1 then 1 else n * fact(n-1) ) Desugared fact should be mutable… Option 2: λ-Calculus + Fix (λ fix ) 6 Translate to statically typed calculus? var fact = function(n) { if (n <= 1) { return 1; } else { return n * fact(n-1); } }; ✗
7
let fact = ref (fix (λfact. λn. if n <= 1 then 1 else n * fact(n-1) )) Recursive call doesn’t go through reference… Okay here, but prevents mutual recursion Option 3: λ-Calculus + Fix + Refs (λ fix,ref ) 7 Translate to statically typed calculus? var fact = function(n) { if (n <= 1) { return 1; } else { return n * fact(n-1); } }; ✗
8
let fact = ref (λn. if n <= 1 then 1 else n * !fact(n-1) ) Yes, this captures the semantics! But how to type check ??? Option 4: λ-Calculus + Fix + Refs (λ ref ) 8 Translate to statically typed calculus? var fact = function(n) { if (n <= 1) { return 1; } else { return n * fact(n-1); } }; ✓
9
let fact = ref (λn. if n <= 1 then 1 else n * !fact(n-1) ) 9
10
10 let fact = ref (λn. 0) in fact := λn. if n <= 1 then 1 else n * !fact(n-1) ; Backpatching Pattern in λ ref fact :: Ref (Int Int) Assignment relies on and guarantees the reference invariant
11
11 let fact = ref (λn. 0) in fact := λn. if n <= 1 then 1 else n * !fact(n-1) ; Backpatching Pattern in λ ref But we want to avoid initializers to: Facilitate JavaScript translation Have some fun! Simple types suffice if reference is initialized with dummy function…
12
Proposal: Open Types for λ ref 12 let fact = ref (λn. if n <= 1 then 1 else n * !fact(n-1) ) fact :: (fact :: Ref (Int Int)) Ref (Int Int) Assuming fact points to an integer function, fact points to an integer function
13
Proposal: Open Types for λ ref 13 let fact = ref (λn. if n <= 1 then 1 else n * !fact(n-1) ) in !fact(5) fact :: (fact :: Ref (Int Int)) Ref (Int Int) Assuming fact points to an integer function, fact points to an integer function Type system must check assumptions at every dereference
14
Proposal: Open Types for λ ref 14 let fact = ref (λn. if n <= 1 then 1 else n * !fact(n-1) ) Motivated by λ ref programs that result from desugaring JavaScript programs
15
Proposal: Open Types for λ ref 15 Motivated by λ ref programs that result from desugaring JavaScript programs let fact = λn. if n <= 1 then 1 else n * fact(n-1) Proposal also applies to, and is easier to show for, the dynamically-scoped λ-calculus (λ dyn ) Bound at the time of call… No need for fix or references
16
Lexical vs. Dynamic Scope 16 λ Environment at definition is frozen in closure… And is used to evaluate function body Explicit evaluation rule for recursion
17
λ dyn Lexical vs. Dynamic Scope 17 λ Bare lambdas, so all free variables resolved in calling environment
18
λ dyn Lexical vs. Dynamic Scope 18 λ No need for fix construct
19
Open Types for λ dyn 19 Types (Base or Arrow) Open Types Type Environments Open Type Environments
20
Open Types for λ dyn 20 Open Typing Open function type describes environment for function body
21
Open Types for λ dyn 21 Open Typing Open function type describes environment for function body Type environment at function definition is irrelevant
22
Open Types for λ dyn 22 Open Typing STLC + Fix In some sense, extreme generalization of [T-Fix]
23
Open Types for λ dyn 23 Open Typing STLC + Fix
24
Open Types for λ dyn 24 Open Typing For every Rely-set contains Guarantee-set contains (most recent, if multiple)
25
Open Types for λ dyn 25 Open Typing For every Rely-set contains Guarantee-set contains (most recent, if multiple) Discharge all assumptions
26
Open Types for λ dyn 26 Open Typing
27
Examples 27 let fact = λn. if n <= 1 then 1 else n * fact(n-1) in fact 5 fact :: (fact :: Int Int) Int Int
28
Examples 28 let fact = λn. if n <= 1 then 1 else n * fact(n-1) in fact 5 GuaranteeRely fact :: (fact :: Int Int) Int Int ✓
29
Error: var [tock] not found Examples 29 let tick n = if n > 0 then “tick ” ++ tock n else “” in tick 2;
30
Examples 30 let tick n = if n > 0 then “tick ” ++ tock n else “” in tick 2; tick :: (tock :: Int Str) Int Str
31
Examples 31 let tick n = if n > 0 then “tick ” ++ tock n else “” in tick 2; GuaranteeRely tick :: (tock :: Int Str) Int Str ✗
32
“tick tock tick tock ” Examples 32 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in tick 2;
33
Examples 33 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in tick 2; tick :: (tock :: Int Str) Int Str tock :: (tick :: Int Str) Int Str
34
Examples 34 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in tick 2; tick :: (tock :: Int Str) Int Str tock :: (tick :: Int Str) Int Str GuaranteeRely ✓
35
Error: “bad” not a function Examples 35 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in let tock = “bad” in tick 2;
36
Examples 36 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in let tock = “bad” in tick 2; tock :: Str tick :: (tock :: Int Str) Int Str tock :: (tick :: Int Str) Int Str
37
Examples 37 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in let tock = “bad” in tick 2; GuaranteeRely tock :: Str tick :: (tock :: Int Str) Int Str tock :: (tick :: Int Str) Int Str ✗
38
“tick tick ” Examples 38 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in let tock = tick (n-1) in tick 2;
39
Examples 39 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in let tock = tick (n-1) in tick 2; tick :: (tock :: Int Str) Int Str tock :: (tick :: Int Str) Int Str
40
Examples 40 let tick n = if n > 0 then “tick ” ++ tock n else “” in let tock n = “tock ” ++ tick (n-1) in let tock = tick (n-1) in tick 2; GuaranteeRely tick :: (tock :: Int Str) Int Str tock :: (tick :: Int Str) Int Str ✓
41
Recap 41 Open Types capture “late packaging” of recursive definitions in dynamically-scoped languages (Metatheory has not yet been worked) Several potential applications in lexically-scoped languages…
42
Open Types for λ ref 42 For open types in this setting, type system must support strong updates to mutable variables e.g. Thiemann et al. (ECOOP 2010), Chugh et al. (OOPSLA 2012) References in λ ref are similar to dynamically-scoped bindings in λ dyn
43
Open Types for λ ref 43 let tick = ref null in let tock = ref null in tick := λn. if n > 0 then “tick ” ++ !tock(n) else “”; tock := λn. “tock ” ++ !tick(n-1); !tick(2); tick :: (tock :: Ref (Int Str)) Ref (Int Str) tock :: (tick :: Ref (Int Str)) Ref (Int Str) tick :: Ref Null tock :: Ref Null tick :: (tock :: Ref (Int Str)) Ref (Int Str) tock :: Ref Null GuaranteeRely ✓ tick :: (tock :: Ref (Int Str)) Ref (Int Str) tock :: (tick :: Ref (Int Str)) Ref (Int Str)
44
Open Types for Methods 44 let tick n = if n > 0 then “tick ” ++ this.tock(n) else “” in let tock n = “tock ” ++ this.tick(n-1) in let obj = {tick=tick; tock=tock} in obj.tick(2); tick :: (this :: {tock: Int Str}) Int Str tock :: (this :: {tick: Int Str}) Int Str
45
Related Work Dynamic scope in lexical settings for: –Software updates –Dynamic code loading –Global flags Implicit Parameters of Lewis et al. (POPL 2000) –Open types mechanism resembles their approach –We aim to support recursion and references Other related work –Bierman et al. (ICFP 2003) –Dami (TCS 1998), Harper (Practical Foundations for PL) –…–… 45
46
Thanks! 46 Thoughts? Questions? Open Types for Checking Recursion in: 1.Dynamically-scoped λ-calculus 2.Lexically-scoped λ-calculus with references
47
EXTRA SLIDES 47
48
Higher-Order Functions 48 Disallows function arguments with free variables This restriction precludes “downwards funarg problem” To be less restrictive:
49
-17 Partial Environment Consistency 49 let negateInt () = 0 - x in let negateBool () = not x in let x = 17 in negateInt (); negateInt :: (x :: Int) Unit Int negateBool :: (x :: Bool) Unit Bool x :: Int Safe at run-time even though not all assumptions satisfied
50
Partial Environment Consistency 50 To be less restrictive: Only and its transitive dependencies in
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.