Post on 12-Jul-2020
transcript
The Meaning of Multilanguage Programs
Jacob Matthewsjacobm@cs.uchicago.edu
University of Chicago
Robby Findlerrobby@cs.uchicago.edu
University of Chicago
1
2
3
4
5
6
7
8
9
10
11
12
13
How do languages vary?
14
How do languages vary?
differing type systems15
How do languages vary?
differing evaluation rules16
How do languages vary?
differing values17
How do languages vary?
This talk: differing type systems18
How do languages vary?
This talk: differing evaluation rules (a little)19
How do languages vary?
This talk: differing values (a very little)20
e := v | (e e) | (+ e e)v := (! (x) e) | number
C := [] | (v C) | (e C)
C[((! (x) e) v)]"C[e [x := v]]C[(+ n1 n2)]"C[n1+n2]
Scheme
21
e := v | (e e) | (+ e e)v := (! (x : #) e) | number# := int | (# " #)
C := [] | (v C) | (C e)
C[((! (x : #) e) v)]"C[e [x := v]]C[(+ n1 n2)]"C[n1+n2]
ML
22
n $ {0 1 2 ...}% n : int MLNUM
x : # $ %
% x : # MLVAR
[x := #A] + % e : #B
% (! (x : #A) e) : #BMLFUN
% e1 : #1"#2 % e2 : #1
% (e1 e2) : #2MLAPP
% e1 : int % e2 : int% (+ e1 e2) : int MLSUM
ML type system
23
n $ {0 1 2 ...}% n : TST SNUM
x : TST $ %
% x : TST SVAR
[x := TST] + % e : TST% (! (x) e) : TST SFUN
% e1 : TST % e2 : TST% (e1 e2) : TST SAPP
% e1 : TST % e2 : TST% (+ e1 e2) : TST SSUM
Scheme type system
24
The big question:How do we put them together?
25
The big question:How do we put them together?
26
The big question:How do we put them together?
Method 1: lump embedding
27
28
29
30
Anatomy of a Boundary
(MS # TST e)An ML boundary
31
Anatomy of a Boundary
(MS # TST e)"ML outside, Scheme inside"
32
Anatomy of a Boundary
(MS # TST e)The Scheme expression to run
33
Anatomy of a Boundary
(MS # TST e)The ML side's type
34
Anatomy of a Boundary
(MS # TST e)The Scheme side's type
35
Anatomy of a Boundary
(MS # e)... which isn't necessary to write down
36
Anatomy of a Boundary
(SM TST # e)A Scheme boundary
37
Anatomy of a Boundary
(SM TST # e)The Scheme side's type
38
Anatomy of a Boundary
(SM # e)... which isn't necessary to write down
39
Anatomy of a Boundary
(SM # e)The ML side's type
40
e := v | (e e) | (+ e e) | (SM # e)v := (! (x) e) | number
New Scheme grammar
41
e := v | (e e) | (+ e e) | (MS # e)v := (! (x : #) e) | number# := int | (# " #) | TST
New ML grammar
42
(+ (MS int 3) 4)'shouldbe error
43
(+ (MS int 3) 4)'shouldbe error
(+ (MS int (SM int 3)) 4)'shouldbe 7
44
(+ (MS int 3) 4)'shouldbe error
(+ (MS int (SM int 3)) 4)'shouldbe 7
(+ (MS int ((! (x) x) (SM int 3))) 4)'shouldbe 7
45
(+ (MS int 3) 4)'shouldbe error
(+ (MS int (SM int 3)) 4)'shouldbe 7
(+ (MS int ((! (x) x) (SM int 3))) 4)'shouldbe 7
(+ (MS int ((! (x) x) (SM (int " int) F))) 4)'shouldbe error
46
(+ (MS int 3) 4)'shouldbe error
(+ (MS int (SM int 3)) 4)'shouldbe 7
(+ (MS int ((! (x) x) (SM int 3))) 4)'shouldbe 7
(+ (MS int ((! (x) x) (SM (int " int) F))) 4)'shouldbe error
(+ (MS int ((! (x) x) (SM int (! (x : int) x)))) 4)'shouldbe Type error!
47
C := [] | (v C) | (C e) | (MS # C)
C[((! (x : #) e) v)]"C[e [x := v]]C[(+ n1 n2)]"C[n1+n2]
New ML reductions
48
C := [] | (v C) | (C e) | (SM # C)
C[((! (x) e) v)]"C[e [x := v]]C[(+ n1 n2)]"C[n1+n2]
New Scheme reductions
49
How do we know what reduction to use?
C[(+ 1 2)]
C[(+ n1 n2)]"C[n1+n2]C[(+ n1 n2)]"C[n1+n2]
50
How do we know what reduction to use?
C[(+ 1 2)]
C[(+ n1 n2)]"C[n1+n2]C[(+ n1 n2)]"C[n1+n2]
51
How do we know what reduction to use?
C[(+ 1 2)]
C := [] | (v C) | (C e) | (SM # C)C := [] | (v C) | (C e) | (MS # C)
C[(+ n1 n2)]"C[n1+n2]C[(+ n1 n2)]"C[n1+n2]
52
n $ {0 1 2 ...}% n : int MLNUM
x : # $ %
% x : # MLVAR
[x := #A] + % e : #B
% (! (x : #A) e) : #BMLFUN
% e1 : #1"#2 % e2 : #1
% (e1 e2) : #2MLAPP
% e1 : int % e2 : int% (+ e1 e2) : int MLSUM
% e : TST% (MS # e) : # MLBOUNDARY
New ML type system
53
n $ {0 1 2 ...}% n : TST SNUM
x : TST $ %
% x : TST SVAR
[x := TST] + % e : TST% (! (x) e) : TST SFUN
% e1 : TST % e2 : TST% (e1 e2) : TST SAPP
% e1 : TST % e2 : TST% (+ e1 e2) : TST SSUM
% e : #% (SM # e) : TST SBOUNDARY
New Scheme type system
54
Packing and unpacking values
v := (! (x) e) | number | (SM #' v)v := (! (x : #) e) | number | (MS TST v)Where #' = #- {TST}
C[(MS #' (SM #' v))] " C[v]C[(MS #' v)] " Error
55
Packing and unpacking values
v := (! (x) e) | number | (SM #' v)v := (! (x : #) e) | number | (MS TST v)Where #' = #- {TST}
C[(MS #' (SM #' v))] " C[v]C[(MS #' v)] " Error
C[(SM TST (MS TST v))] " C[v]
56
Packing and unpacking values
v := (! (x) e) | number | (SM #' v)v := (! (x : #) e) | number | (MS TST v)Where #' = #- {TST}
C[(MS #' (SM #' v))] " C[v]C[(MS #' v)] " Error
C[(SM TST (MS TST v))] " C[v]C[(SM TST v)] " Won't typecheck!
57
(+ (MS int ((! (x) x) (SM int 3)))4)
58
(+ (MS int ((! (x) (x x))
(! (x) (x x))))4)
59
Aside (#1):What if there were no Earth?
60
61
62
63
; H (hide) : (TST -> TST) -> TST(define H (! (a : (TST -> TST))
(MS TST (! (x) (SM (TST -> TST) a))))); U (unhide) : TST -> (TST -> TST)(define U (! (a : TST)
(MS (TST -> TST) ((SM TST a) 1))))
( (! (x : TST) ((U x) x)) (H (! (x : TST) ((U x) x))))
64
; H (hide) : (TST -> TST) -> TST(define H (! (a : (TST -> TST))
(MS TST (! (x) (SM (TST -> TST) a))))); U (unhide) : TST -> (TST -> TST)(define U (! (a : TST)
(MS (TST -> TST) ((SM TST a) 1))))
( (! (x : TST) ((U x) x)) (H (! (x : TST) ((U x) x))))
65
Theorem:A lump-embedding program that typechecksnever goes wrong
66
Less formal theorem:A lump-embedding program that typechecksnever does anything useful
67
Back to the big question:How else can we put them together?
68
Back to the big question:How else can we put them together?
Method 2: natural embedding
69
70
71
72
Convert equals for equals
(MS int 4)'shouldbe 4
73
Convert equals for equals
(MS int 4)'shouldbe 4
((MS (int -> int) (! (x) x)) 2)'shouldbe 2
74
Convert equals for equals
(MS int 4)'shouldbe 4
((MS (int -> int) (! (x) x)) 2)'shouldbe 2
(MS int (! (x) x))'shouldbe error
75
Convert equals for equals
(MS int 4)'shouldbe 4
((MS (int -> int) (! (x) x)) 2)'shouldbe 2
(MS int (! (x) x))'shouldbe error
(SM int (! (x : int) x))'shouldbe type error
76
How?
(MS int 4)" 4
77
How?
(MS int 4)" 4
(MS (int -> int) (! (x) x))" (! (x : int) x)
78
How?
(MS int 4)" 4
(MS (int -> (! (x) x)))" (! (x : int) x)
79
How?
(MS int 4)" 4
(MS (int -> int) (! (x) x))"
(! (x : int) (MS int ((! (x) x) (SM int x))))
80
How?
(MS int 4)" 4
(MS (int -> int) (! (x) x))"
(! (x : int) (MS int ((! (x) x) (SM int x))))
But what if the Scheme code doesn't produce an int?
81
Even worse:
(! (x : int) (MS (int -> int)
((! (a) (! (b) (! (c) c)))(MS int x))))
What if ML can't immediately tellthat something is wrong?
82
(MS ((int -> int) -> (int -> int)) F)
"
(! (x : (int -> int)) (MS (int -> int)
(F (SM (int -> int) x))))
83
(MS ((int -> int) -> (int -> int)) F)
"
(! (x : (int -> int)) (MS (int -> int)
(G (int -> int)(F (SM (int -> int) x)))))
guard the context from bad Scheme values
84
(MS ((int -> int) -> (int -> int)) F)
"
(! (x : (int -> int)) (MS (int -> int)
(G (int -> int)(F (G (int -> int)
(SM (int -> int) x))))))
guard the ML function from wrong uses
85
(MS ((int -> int) -> (int -> int)) F)
"
(! (x : (int -> int)) (MS (int -> int)
(G+ (int -> int) (F (G- (int -> int)
(SM (int -> int) x))))))
These are two different jobs
86
Anatomy of a Guard
(G+ # v)All guards are projections on values
87
Anatomy of a Guard
(G+ # v)All guards are in Scheme
88
Anatomy of a Guard
(G+ # v)Positive guards (jailors): "Make v behave like a tau"
89
Anatomy of a Guard
(G+ # v)v is the value we're projecting
90
Anatomy of a Guard
(G+ # v)the type v must behave like
91
Anatomy of a Guard
(G- # v)Negative guards (bodyguards): "Make the context treat v like a tau"
92
e := v | (e e) | (+ e e) | (SM # e) | (G+ # e) | (G- # e)
v := (! (x) e) | number
C := [] | (v C) | (C e) | (SM # C) | (G+ # C) | (G- # C)
93
e := v | (e e) | (+ e e) | (MS # e)v := (! (x : #) e) | number# := int | (# " #)
C := [] | (v C) | (C e) | (MS # C)
94
(G+ int n)" nif n is a number, error otherwise
(G+ (#1 -> #2) f)" (! (x) (G+ #1 ((f (G- #2 x)))))
if f is a procedure value, error otherwise
95
(G+ int n)" nif n is a number, error otherwise
(G+ (#1 -> #2) f)" (! (x) (G+ #1 ((f (G- #2 x)))))
if f is a procedure value, error otherwise
(G- int n)" n
(G- (#1 -> #2) f)" (! (x) (G- #1 ((f (G+ #2 x)))))
No direct dynamic checks - negative guards are trusting
96
Aside (#2):What if there were no Mars?
97
98
99
100
• Guards don't care about the type system (only vice versa)
• Scheme embedded in Scheme could use the same technique, anddoes
101
Back to the big question again:How well have we answered it?
102
• A method for modeling multilanguage semantics
• Boundaries, recursive contexts
• Simple but models a lot
• This is an interesting way to talk about language interoperation!
103
The End
104