Because propositions
in such a logic may no
longer be freely copied or ig- nored, this suggests under- standing propositions in sub- structural logics as repre- senting resources rather than truth.
Because propositions in such a logic may no longer be freely copied - - PowerPoint PPT Presentation
Because propositions in such a logic may no longer be freely copied or ig- standing propositions in sub- structural logics as repre- senting resources rather than truth. nored, this suggests under- Programming with Affine Types CS 51 &
Because propositions
in such a logic may no
longer be freely copied or ig- nored, this suggests under- standing propositions in sub- structural logics as repre- senting resources rather than truth.
let deposit (arr: int array) (acct: int) (amt: int) = Array.set arr acct (Array.get arr acct + amt)
3
let deposit (arr: int array) (acct: int) (amt: int) = Array.set arr acct (Array.get arr acct + amt)
3
let deposit (arr: int array) (acct: int) (amt: int) = Array.set arr acct (Array.get arr acct + amt)
3
let deposit (l: lock) (arr: int array) (acct: int) (amt: int) = Lock.acquire l; Array.set arr acct (Array.get arr acct + amt); Lock.release l
4
let deposit (l: lock) (arr: int array) (acct: int) (amt: int) = Lock.acquire l; Array.set arr acct (Array.get arr acct + amt); Lock.release l
4
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } lock_sock(sk); ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ release_sock(sk); LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ release_sock(sk); LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ release_sock(sk); LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
(Leino et al. 2009)
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ release_sock(sk); LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
(Leino et al. 2009)
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ release_sock(sk); LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
(Leino et al. 2009)
5
int udp_sendmsg(struct sock *sk, struct msghdr *msg, …) { . . . lock_sock(sk); if (unlikely(sk→pending)) { /* Socket is already corked while preparing it */ /* … which is an evident application bug. –ANK */ release_sock(sk); LIMIT_NETDEBUG(KERN_DEBUG “udp cork app bug 2”); return -EINVAL; } ret = ip_append_data(sk, msg→msg_iov, ulen, …); . . . release_sock(sk); return ret; }
(Leino et al. 2009)
5
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with None send Reject ch Some (r, price) send (Offer price) ch; match recv ch with Accept send (Resource r) ch Reject () let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with Reject None Offer price if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () Pattern match failure 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop () 6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop ()
(Fähndrich et al. 2006)
6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop ()
(Fähndrich et al. 2006)
6
type bid_msg = Request of string
| Offer of int | Reject | Accept | Resource of resource
type bid_chan = bid_msg chan let seller ch = let Request name = recv ch in match lookup name with
| None →
send Reject ch
| Some (r, price) →
send (Offer price) ch; match recv ch with
| Accept →
send (Resource r) ch
| Reject → ()
let buyer name limit ch = send (Request name) ch; let rec loop () = match recv ch with
| Reject → None | Offer price →
if price ≤ limit then send Accept ch; let Resource r = recv ch in Some r else send (Offer limit) ch; loop () in loop ()
(Fähndrich et al. 2006)
6
Problem: Locking Message passing Both Solution: Static permissions Session types ? in Chalice in Sing#
7
Problem: Locking Message passing Both Solution: Static permissions Session types ? in Chalice in Sing#
7
Special Purpose General Purpose Theoretical Practical
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F
URAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F
URAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F
URAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
Special Purpose General Purpose Theoretical Practical
m e m
y r e g i
s
Cyclone
p e r m i s s i
s
Chalice
s e s s i
t y p e s
Sing#, Moose
t y p e s t a t e
Vault, Plaid
f r a c t i
a l p e r m i s s i
s
Boyland 2003
s e s s i
t y p e s
Honda 1998, Vasconcelos 2004
u n i q u e c a p a b i l i t i e s
Capability Calculus
Use types
F◦
λURAL
ILL LNL
8
9
U Affine
nlimited
9
U A
nlimited
9
U A ≤ 1
9
U A
9
U A
9
U A
think ML pay-as-you-go
9
U A
think ML pay-as-you-go stateful type systems as libraries
9
U A
think ML pay-as-you-go stateful type systems as libraries Alms
9
U A
think ML pay-as-you-go stateful type systems as libraries Alms
language design core model prototype implementation
9
U A
think ML pay-as-you-go stateful type systems as libraries Alms
language design core model prototype implementation
9
OCaml Alms Affine types No Yes First-class polymorphism Awkward Yes Type inference Yes Yes Modules Yes Yes Opaque signatures Yes Yes Algebraic data types Yes Yes Pattern matching Yes Yes Concurrency Yes Yes Exceptions Yes Yes Functors, classes, … Yes No
11
val nth : int → ’a list → ’a option #- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) Error: This expression has type char but an expression was expected of type int #- (nth 1 [1,3,5], nth 1 [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
12
val nth : int → ’a list → ’a option #- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) Error: This expression has type char but an expression was expected of type int #- (nth 1 [1,3,5], nth 1 [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
12
val nth : int → ’a list → ’a option #- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) Error: This expression has type char but an expression was expected of type int #- (nth 1 [1,3,5], nth 1 [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
12
val nth : int → ’a list → ’a option #- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) Error: This expression has type char but an expression was expected of type int #- (nth 1 [1,3,5], nth 1 [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
12
val nth : int → ’a list → ’a option #- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) Error: This expression has type char but an expression was expected of type int #- (nth 1 [1,3,5], nth 1 [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
12
val nth : ∀
#- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) Error: This expression has type char but an expression was expected of type int #- (nth 1 [1,3,5], nth 1 [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
12
val nth : int → ∀
#- let second = nth 1 in (second [1,3,5], second [2,4,6]) it : int option × int option = (Some 3, Some 4) #- let second = nth 1 in (second [1,3,5], second [’a’,’b’,’c’]) it : int option × char option = (Some 3, Some ’b’)
13
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ’a. ’a × (’a string) bee : ’a. ’a × (’a string) #- let both = [one, bee] both : ( ’a. ’a × (’a string)) list #- let show ((x, f) : ’a. ’a × (’a string)) = f x show : ( ’a. ’a × (’a string)) string #- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : ( ’a. ’a × (’a string)) list #- let show ((x, f) : ’a. ’a × (’a string)) = f x show : ( ’a. ’a × (’a string)) string #- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : (∃
#- let show ((x, f) : ’a. ’a × (’a string)) = f x show : ( ’a. ’a × (’a string)) string #- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : (∃
#- let show ((x, f) : ∃
show : (∃
#- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : (∃
#- let show ((x, f) : ∃
show : (∃
#- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : (∃
#- let show ((x, f) : ∃
show : (∃
#- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : (∃
#- let show ((x, f) : ∃
show : (∃
#- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = bee in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
#- let one = (1, string_of_int) : ∃
#- let bee = (’b’, string_of_char) : ∃
bee : ∃
#- let both = [one, bee] both : (∃
#- let show ((x, f) : ∃
show : (∃
#- map show both it : string list = [”1”, ”b”] #- let (x, f) = one in let (y, g) = one in f y Error: This expression has type ’_a2 but an expression was expected of type ’_a6
14
let deposit (arr: int array) (acct: int) (amt: int) = Array.set arr acct (Array.get arr acct + amt)
15
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int ’a ’a array val set : ’a array int ’a ’a array val get : ’a array int ’a × ’a array end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int ’a ’a array val set : ’a array int ’a ’a array val get : ’a array int ’a × ’a array end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
module AfArray : AF_ARRAY = struct type ’a array = ’a Array.array (* U A *) let new = Array.new let set arr ix v = Array.set arr ix v; arr let get arr ix = (Array.get arr ix, arr) end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
module AfArray : AF_ARRAY = struct type ’a array = ’a Array.array (* U ⊑ A *) let new = Array.new let set arr ix v = Array.set arr ix v; arr let get arr ix = (Array.get arr ix, arr) end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
module AfArray : AF_ARRAY = struct type ’a array = ’a Array.array (* U A *) let new = Array.new let set arr ix v = Array.set arr ix v; arr let get arr ix = (Array.get arr ix, arr) end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
module AfArray : AF_ARRAY = struct type ’a array = ’a Array.array (* U A *) let new = Array.new let set arr ix v = Array.set arr ix v; arr let get arr ix = (Array.get arr ix, arr) end
16
module Array : sig type ’a array : U val new : int → ’a → ’a array val set : ’a array → int → ’a → unit val get : ’a array → int → ’a end module type AF_ARRAY = sig type ’a array : A val new : int → ’a → ’a array val set : ’a array → int → ’a → ’a array val get : ’a array → int → ’a × ’a array end
module AfArray : AF_ARRAY = struct type ’a array = ’a Array.array (* U A *) let new = Array.new let set arr ix v = Array.set arr ix v; arr let get arr ix = (Array.get arr ix, arr) end
16
let deposit arr acct amt = let (balance, arr) = AfArray.get arr acct in AfArray.set arr acct (balance + amt)
17
let deposit arr acct amt = let (balance, arr) = AfArray.get arr acct in AfArray.set arr acct (balance + amt)
17
let deposit arr acct amt = let (balance, arr) = AfArray.get arr acct in r := arr; AfArray.set arr acct (balance + amt)
17
let deposit arr acct amt = let (balance, arr) = AfArray.get arr acct in r := arr; AfArray.set arr acct (balance + amt)
17
let deposit arr acct amt = let (balance, arr) = AfArray.get arr acct in r := arr; AfArray.set arr acct (balance + amt) Type error at afarray_test.alms:2:17-20: Qualifier inequality unsatisfiable: Attempted to use an affine type where only an unlimited type is permitted.
17
module type CAP_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap end
18
module type CAP_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap end
18
module type CAP_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap end
18
module type CAP_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap end
18
module type CAP_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap end
18
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in let (balance, arrcap) = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in let balance = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in let balance = get arr acc arrcap in let arrcap = set arr acct (balance + amt) arrcap in release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in let balance = get arr acc arrcap in set arr acct (balance + amt) arrcap; release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in set arr acct (get arr acc arrcap + amt) arrcap; release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in set arr acct (get arr acc arrcap + amt) arrcap; release arrcap
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in set arr acct (get arr acc arrcap + amt) arrcap; release arrcap
(and it’s not far to read/write locks, fractional permissions, …)
19
module type LOCK_ARRAY = sig type (’a,’t) array : U type ’t cap : A val new : int → ’a → ∃
val set : (’a,’t) array → int → ’a → ’t cap → ’t cap val get : (’a,’t) array → int → ’t cap → ’a × ’t cap val acquire : (’a,’t) array → ’t cap val release : (’a,’t) array → ’t cap → unit end let deposit arr acct amt = let !arrcap = acquire arr in set arr acct (get arr acc arrcap + amt) arrcap; release arrcap
(and it’s not far to read/write locks, fractional permissions, …)
19
S B
B: string reject
S: int accept S: resource counter B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a send (* send an ’a *) type ’a recv (* receive an ’a *) type (’a,’s) seq (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) (* Examples: * (string recv, done) seq * (int send, (string recv, done) seq) seq
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ’a (!) (* send an ’a *) type ’a (?) (* receive an ’a *) type (’a,’s) (;) (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) (* Examples: * (string (?), done) (;) * (int (?), (string (?), done) (;)) (;)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) (* Examples: * ?string; done * !int; ?string; done
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) (* Examples: * (?string; done) + done * !string; (done & (?int; done))
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type prot = !string; offer and
= done & (?int; respond) and respond = (?resource; done) + (!int; offer)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer)
20
S B
B: string 1 2 S: int 1 S: resource 2 B: int
type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer)
20
module type SESSION_TYPES = sig type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type ’s chan : A val send : ’a (!’a; ’s) chan ’s chan val recv : (?’a; ’s) chan ’a × ’s chan val sel1 : (’s + ’t) chan ’s chan val sel2 : (’s + ’t) chan ’t chan val follow : (’s & ’t) chan (’s chan, ’t chan) either . . . end
21
module type SESSION_TYPES = sig type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type ’s chan : A val send : ’a (!’a; ’s) chan ’s chan val recv : (?’a; ’s) chan ’a × ’s chan val sel1 : (’s + ’t) chan ’s chan val sel2 : (’s + ’t) chan ’t chan val follow : (’s & ’t) chan (’s chan, ’t chan) either . . . end
21
module type SESSION_TYPES = sig type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type ’s chan : A val send : ’a → (!’a; ’s) chan → ’s chan val recv : (?’a; ’s) chan → ’a × ’s chan val sel1 : (’s + ’t) chan ’s chan val sel2 : (’s + ’t) chan ’t chan val follow : (’s & ’t) chan (’s chan, ’t chan) either . . . end
21
module type SESSION_TYPES = sig type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type ’s chan : A val send : ’a → (!’a; ’s) chan → ’s chan val recv : (?’a; ’s) chan → ’a × ’s chan val sel1 : (’s + ’t) chan → ’s chan val sel2 : (’s + ’t) chan → ’t chan val follow : (’s & ’t) chan (’s chan, ’t chan) either . . . end
21
module type SESSION_TYPES = sig type done type ! ’a (* send an ’a *) type ? ’a (* receive an ’a *) type ’a ; ’s (* do ’a , then ’s *) type ’r + ’s (* choose between ’r and ’s *) type ’r & ’s (* other side chooses *) type ’s chan : A val send : ’a → (!’a; ’s) chan → ’s chan val recv : (?’a; ’s) chan → ’a × ’s chan val sel1 : (’s + ’t) chan → ’s chan val sel2 : (’s + ’t) chan → ’t chan val follow : (’s & ’t) chan → (’s chan, ’t chan) either . . . end
21
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !ch = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !(ch: prot chan) = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !(ch: prot chan) = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel2 ch; Some (recv ch) else sel1 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !(ch: prot chan) = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel2 ch; Some (recv ch) else sel1 ch; send limit ch; loop () in loop () Type error at buyer.alms:12:31-33: Cannot subtype: actual: !int; offer expected: ?’_a; ’_b
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !(ch: prot chan) = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !(ch: prot chan) = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
(or you can roll your own)
22
type prot = !string; offer and offer = done & (?int; respond) and respond = (?resource; done) + (!int; offer) let buyer name limit !(ch: prot chan) = send name ch; let rec loop () = match follow ch with
if recv ch ≤ limit then sel1 ch; Some (recv ch) else sel2 ch; send limit ch; loop () in loop ()
(or you can roll your own)
22
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurry in ILL (Bierman 1993):
f promote ( p let (x, y) = derelict p in derelict (derelict f x) y) : !(’a !(’b ’c)) !(!(’a ’b) ’c) f p let (x, y) = derelict p in derelict (f x) y : (’a !(’b ’c)) !(’a ’b) ’c
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurry in ILL (Bierman 1993):
f promote ( p let (x, y) = derelict p in derelict (derelict f x) y) : !(’a !(’b ’c)) !(!(’a ’b) ’c) f p let (x, y) = derelict p in derelict (f x) y : (’a !(’b ’c)) !(’a ’b) ’c
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurry in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c) f p let (x, y) = derelict p in derelict (f x) y : (’a !(’b ’c)) !(’a ’b) ’c
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Wrong defaults
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Wrong defaults Frightening types
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Wrong defaults Frightening types Derelict & promote
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Wrong defaults Frightening types Derelict & promote Too much repetition
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Wrong defaults Frightening types Derelict & promote Too much repetition Usage kinds Dependent kinds Dereliction subtyping Principal promotion Type inference
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Wrong defaults Frightening types Derelict & promote Too much repetition Usage kinds Dependent kinds Dereliction subtyping Principal promotion Type inference
Uncurry in Alms:
f (x,y) f x y : (‘a
‘d
‘b ‘c) ‘a × ‘b
‘d
‘c
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Uncurry in Alms:
: (‘a
‘d
‘d
24
Uncurry in ML:
: (’a → ’b → ’c) → ’a × ’b → ’c
Uncurries in ILL (Bierman 1993):
let (x, y) = derelict p in derelict (derelict f x) y) : !(’a ⊸ !(’b ⊸ ’c)) ⊸ !(!(’a ⊗ ’b) ⊸ ’c)
derelict (f x) y : (’a ⊸ !(’b ⊸ ’c)) ⊸ !(’a ⊗ ’b) ⊸ ’c
Uncurry in Alms:
: (‘a
‘d
‘d
24
#- λ
it : ‘a ‘a #- x (x, x) it : ’a ’a × ’a #- (x, y) (y, x) it : ‘a × ‘b ‘b × ‘a
25
#- λ
it : ‘a → ‘a #- x (x, x) it : ’a ’a × ’a #- (x, y) (y, x) it : ‘a × ‘b ‘b × ‘a
25
#- λ
it : ‘a → ‘a #- λ
it : ’a ’a × ’a #- (x, y) (y, x) it : ‘a × ‘b ‘b × ‘a
25
#- λ
it : ‘a → ‘a #- λ
it : ’a → ’a × ’a #- (x, y) (y, x) it : ‘a × ‘b ‘b × ‘a
25
#- λ
it : ‘a → ‘a #- λ
it : ’a → ’a × ’a #- λ
it : ‘a × ‘b ‘b × ‘a
25
#- λ
it : ‘a → ‘a #- λ
it : ’a → ’a × ’a #- λ
it : ‘a × ‘b → ‘b × ‘a
25
#- λ
it : (‘a
‘c
‘b) ‘a
‘c
‘b #- f x f (f x) it : (‘a ‘a) ‘a ‘a #- f x f (x, x) it : (’a × ’a
‘c
‘b) ’a
‘c
‘b #- f x let y = f x in (y, y) it : (‘a
‘c
’b) ‘a
‘c
’b × ’b #- f x (f x, f x) it : (’a ‘b) ’a ‘b × ‘b
26
#- λ
it : (‘a
‘c
‘c
#- f x f (f x) it : (‘a ‘a) ‘a ‘a #- f x f (x, x) it : (’a × ’a
‘c
‘b) ’a
‘c
‘b #- f x let y = f x in (y, y) it : (‘a
‘c
’b) ‘a
‘c
’b × ’b #- f x (f x, f x) it : (’a ‘b) ’a ‘b × ‘b
26
#- λ
it : (‘a
‘c
‘c
#- λ
it : (‘a → ‘a) → ‘a → ‘a #- λ
it : (’a × ’a
‘c
‘c
#- λ
it : (‘a
‘c
‘c
#- λ
it : (’a ‘b) ’a ‘b × ‘b
26
#- λ
it : (‘a
‘c
‘c
#- λ
it : (‘a → ‘a) → ‘a → ‘a #- λ
it : (’a × ’a
‘c
‘c
#- λ
it : (‘a
‘c
‘c
#- λ
it : (’a → ‘b) → ’a → ‘b × ‘b
26
#- let rec fold_right f z xs = match xs with #=
#=
fold_right : (’a → ‘b list
A
‘c → ’a list → ‘b list #- let rec fold_right f z xs = match xs with #= [] [] #= x::xs’ f x (fold_right f z xs’) fold_right : (‘a ‘b list
A
‘b list) ‘c ‘a list ‘b list
27
#- let rec fold_right f z xs = match xs with #=
#=
fold_right : (’a → ‘b list
A
‘c → ’a list → ‘b list #- let rec fold_right f z xs = match xs with #= [] [] #= x::xs’ f x (fold_right f z xs’) fold_right : (‘a ‘b list
A
‘b list) ‘c ‘a list ‘b list
27
#- let rec fold_right f z xs = match xs with #=
#=
fold_right : (’a → ‘b list
A
‘c → ’a list → ‘b list #- let rec fold_right f z xs = match xs with #=
#=
fold_right : (‘a → ‘b list
A
‘c → ‘a list → ‘b list
27
(should support user-defined duplication)
(exploit affine types for efficiency?)
29
30
30