SLIDE 1 Logical Types for Untyped Languages
Sam Tobin-Hochstadt & Matthias Felleisen PLT @ Northeastern University ICFP, September 27, 2010
SLIDE 2 Types for Untyped Languages:
- Ruby [Furr et al 09]
- Perl [Tang 06]
- Thorn [Wrigstad et al 09]
- ActionScript [Adobe 06]
- Typed Racket
SLIDE 3 Types for Untyped Languages:
- Reynolds 68
- Cartwright 75
- Wright & Cartwright 94
- Henglein & Rehof 95
SLIDE 4
"Some account should be taken of the premises in conditional expressions." Reynolds, 1968
SLIDE 5
"Type testing predicates aggravate the loss of static type information." Henglein & Rehof, 1995
SLIDE 6
Types and Predicates
SLIDE 7
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))]))
SLIDE 8
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) n : Peano n n : Peano
SLIDE 9
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) n : Peano n n : Peano
SLIDE 10
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) n : 'Z n : 'Z
SLIDE 11
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) n : (List 'S Peano) n n : List 'S Peano
SLIDE 12
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))]))
SLIDE 13
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) s : (U String Symbol) s* : (U String Symbol) s s : U String Symbol s* s* : U String Symbol
SLIDE 14
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) s : String s* : String s s : String s* s* : String
SLIDE 15
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) s : String s* : Symbol s s : String s* s* : Symbol
SLIDE 16
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) s : Symbol s* : String s s : Symbol s* s* : String
SLIDE 17
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) s : Symbol s* : Symbol s s : Symbol s* s* : Symbol
SLIDE 18
Types and Propositions
SLIDE 19
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))]))
SLIDE 20
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) n : (List 'S Peano) add1 convert rest n n : List 'S Peano
SLIDE 21
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) ⊢ (List 'S Peano) @ n add1 convert rest n ⊢ List 'S Peano @ n
SLIDE 22
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) ⊢ (List 'S Peano) @ n symbol? n ⊢ Symbol @ n
SLIDE 23
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) ⊢ Peano @ n ⊢ Symbol @ n ⊢ (List 'S Peano) @ n symbol? n ⊢ Symbol @ n
SLIDE 24
(define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))])) ⊢ (U 'Z (List 'S Peano)) @ n ⊢ Symbol @ n ⊢ (List 'S Peano) @ n symbol? n ⊢ Symbol @ n
SLIDE 25
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))]))
SLIDE 26
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) ⊢ String @ s ⊢ String @ s* string-append s s* ⊢ String @ s ⊢ String @ s*
SLIDE 27
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) ⊢ String @ s ∧ String @ s* ⊢ String @ s ⊢ String @ s* string? s String @ s string? s* String @ s*
SLIDE 28
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) ⊢ Symbol @ s* string-append s symbol->string s* Symbol @ s*
SLIDE 29
(: combine : (U String Symbol) (U String Symbol) -> String) (define (combine s s*) (cond [(and (string? s) (string? s*)) (string-append s s*)] [(string? s) (string-append s (symbol->string s*))] [(string? s*) (string-append (symbol->string s) s*)] [else (string-append (symbol->string s) (symbol->string s*))])) ⊢ String @ s ⊢ String @ s ⊃ String @ s* ⊢ Symbol @ s* and string? s string? s* String @ s ⊃ String @ s* string? s String @ s
SLIDE 30
(string? s )
SLIDE 31
(string? s ) String @ s
SLIDE 32
(string? s ) String @ s | String @ s
SLIDE 33
(x:Any -> Bool : String@x | String@x) s
(string? s ) String @ s | String @ s
x:Any -> Bool : String@x | String@x
string? s
s
SLIDE 34
Latent Propositions
(x:Any -> Bool : String@x | String@x) Objects s
(string? s ) String @ s | String @ s
Propositions
x:Any -> Bool : String@x | String@x
string? s
s
SLIDE 35
Latent Propositions
(x:Any -> Bool : String@x | String@x) Objects car(s)
(string? (car s)) String @ car(s) | String @ car(s)
Propositions
x:Any -> Bool : String@x | String@x
string? car s
car(s)
SLIDE 36
(λ ([s : (Pair Any Any)]) (string? (car s))) String @ car(s) | String @ car(s)
SLIDE 37
(λ ([s : (Pair Any Any)]) (string? (car s))) (s:(Pair Any Any) -> Bool : String @ car(s) | String @ car(s))
SLIDE 38
Propositional Logic
SLIDE 39
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o
SLIDE 40
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o e ::= n | c | (λ x : T . e) | (e e) | (if e e e)
SLIDE 41
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o T ::= Number | (U T ...) | #t | #f | (x:T -> T : φ|φ)
SLIDE 42
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o φ ::= T@π(x) | T@π(x) | φ1 ∨ φ2 | φ1 ∧ φ2 | φ1 ⊃ φ2
SLIDE 43
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o Γ ::= x:T ...
SLIDE 44
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o Γ ::= x:T T@π(x) ...
SLIDE 45
Judgments Γ ⊢ e : T ; φ1 | φ2 ; o Γ ::= x:T T@π(x) φ ...
SLIDE 46
Judgments Γ ⊢ φ
SLIDE 47
Judgments Γ ⊢ φ Number @ x ∨ String @ y , Number @ x ⊢ String @ y
SLIDE 48
Typing (if e1 e2 e3)
SLIDE 49
Typing Γ,φ+ ⊢ e2 : T ; φ1+|φ1- ; o Γ,φ- ⊢ e3 : T ; φ2+|φ2- ; o Γ ⊢ e1 : T' ; φ+|φ- ; o' (if e1 e2 e3)
SLIDE 50
Typing Γ,φ+ ⊢ e2 : T ; φ1+|φ1- ; o Γ,φ- ⊢ e3 : T ; φ2+|φ2- ; o Γ ⊢ e1 : T' ; φ+|φ- ; o' Γ ⊢ (if e1 e2 e3) : T ; φ1+∨φ2+ | φ1-∨φ2- ; o
SLIDE 51
Typing Γ ⊢ x : T
SLIDE 52
Typing Γ ⊢ Tx Γ ⊢ x : T
SLIDE 53
Evaluation
SLIDE 54
Scaling
Multiple Arguments Multiple Values User-defined Datatypes Local Binding
Adapting
Mutable Structures Mutable Variables
SLIDE 55
Local Binding Γ ⊢ e0 : S ; φ*+ | φ*- ; o Γ, S@x, #f @ x ⊃ φ*+ ⊢ e1 : T ; φ+ | φ- ; o* Γ ⊢ (let [x e0] e1) : T[o/x] ; φ+ | φ- [o/x] ; o*[o/x]
SLIDE 56 Empirical Evaluation
Estimated usage of two idioms in Racket code base (600k lines)
- Local binding with or: ~470 uses
- Predicates with Selectors: ~440 uses
SLIDE 57
Prior Work
None of the Examples Shivers 91, Henglein & Rehof 95, Crary et al 98, ... Just convert Aiken et al 94, Wright 94, Flanagan 97, Komondoor et al 2005 Everything but abstraction Bierman et al 2010
SLIDE 58
Conclusions
Propositions can relate types and terms
SLIDE 59
Conclusions
Propositions can relate types and terms Existing programs are a source of type system ideas
SLIDE 60
Thank You
Code and Documentation http://www.racket-lang.org samth@ccs.neu.edu
SLIDE 61
Thank You
Code and Documentation http://www.racket-lang.org samth@ccs.neu.edu