Slide 1

Slide 1 text

Evolving Existing Languages The Typed Racket Experience Sam Tobin-Hochstadt PLT @ Northeastern University Nov 29, 2010 Indiana University

Slide 2

Slide 2 text

Programs Evolve

Slide 3

Slide 3 text

Automated Testing (for ([f (in-directory (find-collects-dir))] #:when (file-exists? f)) (system* "racket" "-t" (path->string f))) 3 lines

Slide 4

Slide 4 text

DrDr

Slide 5

Slide 5 text

BuildBot

Slide 6

Slide 6 text

Languages Must Evolve

Slide 7

Slide 7 text

What is Language Evolution? Smooth Interoperation Easy Migration Comprehensive Reuse

Slide 8

Slide 8 text

Typed Racket Smooth Interoperation - Typed/Untyped Interaction Easy Migration - Types for Existing Programs Comprehensive Reuse - Building on Existing Languages

Slide 9

Slide 9 text

Typed Racket in 3 Slides

Slide 10

Slide 10 text

Hello World hello #lang racket (printf "Hello World\n")

Slide 11

Slide 11 text

Hello World hello #lang typed/racket (printf "Hello World\n")

Slide 12

Slide 12 text

Functions ack #lang racket ; ack : Integer Integer -> Integer (define (ack m n) (cond [(<= m 0) (+ n 1)] [(<= n 0) (ack (- m 1) 1)] [else (ack (- m 1) (ack m (- n 1)))])) (ack 2 3)

Slide 13

Slide 13 text

Functions ack #lang typed/racket (: ack : Integer Integer -> Integer) (define (ack m n) (cond [(<= m 0) (+ n 1)] [(<= n 0) (ack (- m 1) 1)] [else (ack (- m 1) (ack m (- n 1)))])) (ack 2 3)

Slide 14

Slide 14 text

Modules ack #lang racket ; ack : Integer Integer -> Integer (define (ack m n) (cond [(<= m 0) (+ n 1)] [(<= n 0) (ack (- m 1) 1)] [else (ack (- m 1) (ack m (- n 1)))])) compute #lang racket (require ack) (ack 2 3)

Slide 15

Slide 15 text

Modules ack #lang typed/racket (: ack : Integer Integer -> Integer) (define (ack m n) (cond [(<= m 0) (+ n 1)] [(<= n 0) (ack (- m 1) 1)] [else (ack (- m 1) (ack m (- n 1)))])) compute #lang racket (require ack) (ack 2 3)

Slide 16

Slide 16 text

Modules ack #lang racket ; ack : Integer Integer -> Integer (define (ack m n) (cond [(<= m 0) (+ n 1)] [(<= n 0) (ack (- m 1) 1)] [else (ack (- m 1) (ack m (- n 1)))])) compute #lang typed/racket (require [ack (Integer Integer -> Integer)]) (ack 2 3)

Slide 17

Slide 17 text

Modules ack #lang typed/racket (: ack : Integer Integer -> Integer) (define (ack m n) (cond [(<= m 0) (+ n 1)] [(<= n 0) (ack (- m 1) 1)] [else (ack (- m 1) (ack m (- n 1)))])) compute #lang typed/racket (require ack) (ack 2 3)

Slide 18

Slide 18 text

Interoperating with Existing Languages

Slide 19

Slide 19 text

Typed & Untyped server #lang typed/racket (: add5 (Number -> Number)) (define (add5 x) (+ x 5)) client #lang racket (require server) (add5 7)

Slide 20

Slide 20 text

Typed & Untyped Untyped code can make mistakes server #lang typed/racket (: add5 (Number -> Number)) (define (add5 x) (+ x 5)) client #lang racket (require server) (add5 "seven")

Slide 21

Slide 21 text

Typed & Untyped Untyped code can make mistakes server #lang typed/racket (: add5 (Number -> Number)) (define (add5 x) ) client #lang racket (require server) (add5 "seven") +: expects type as 1st argument

Slide 22

Slide 22 text

Typed & Untyped Catch errors dynamically at the boundary server #lang typed/racket (: add5 (Number -> Number)) (define (add5 x) (+ x 5)) client #lang racket (require server) (add5 "seven") client broke the contract on add5

Slide 23

Slide 23 text

Typed & Untyped Catch errors dynamically at the boundary server #lang racket (define (add5 x) "x plus 5") client #lang typed/racket (require server [add5 (Number -> Number)]) (add5 7) server interface broke the contract on add5

Slide 24

Slide 24 text

Typed & Untyped Catch errors dynamically at the boundary server #lang typed/racket (: addx (Number -> (Number -> Number))) (define (addx x) (lambda (y) (+ x y))) client #lang racket (require server) ((addx 7) 'bad) client broke the contract on add5

Slide 25

Slide 25 text

The Blame Theorem If the program raises a contract error, the blame is not assigned to a typed module.

Slide 26

Slide 26 text

The Blame Theorem Well-typed modules can’t get blamed. [Wadler & Findler]

Slide 27

Slide 27 text

The Blame Theorem Allows local reasoning about typed modules, without changing untyped modules. Choose how much static checking you want.

Slide 28

Slide 28 text

Checking Existing Languages Occurrence Typing Variable-Arity Refinement Types Ad-Hoc Data

Slide 29

Slide 29 text

Types for Existing Programs occur #lang typed/racket (define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))]))

Slide 30

Slide 30 text

Types for Existing Programs refine #lang typed/racket (: check : String -> (Refinement sql-safe?)) (define (check s) (if (sql-safe? s) s (error "unsafe string!")))

Slide 31

Slide 31 text

Types for Existing Programs union #lang typed/racket (define-type BT (U Number (Pair BT BT))) (: sizeof : BT -> Number) (define (sizeof b) (if (number? b) 1 (+ 1 (sizeof (car b)) (sizeof (cdr b)))))

Slide 32

Slide 32 text

Types for Existing Programs varar #lang typed/racket (: wrap (∀ (B A ...) (A ... -> B) -> (A ... -> B))) (define (wrap f) (λ args (printf "args are: ~a\n" args) (apply f args)))

Slide 33

Slide 33 text

Occurrence Typing (define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))]))

Slide 34

Slide 34 text

Occurrence Typing (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 35

Slide 35 text

Occurrence Typing (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 36

Slide 36 text

Occurrence Typing (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 0 n : 'Z

Slide 37

Slide 37 text

Occurrence Typing (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 38

Slide 38 text

Occurrence Typing (: 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 39

Slide 39 text

Occurrence Typing (: 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 40

Slide 40 text

Occurrence Typing (: 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 41

Slide 41 text

Occurrence Typing (: 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 42

Slide 42 text

Occurrence Typing (: 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 43

Slide 43 text

Occurrence Typing (: 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 44

Slide 44 text

Occurrence Typing (define-type Peano (U 'Z (List 'S Peano))) (: convert : Peano -> Number) (define (convert n) (cond [(symbol? n) 0] [else (add1 (convert (rest n)))]))

Slide 45

Slide 45 text

Occurrence Typing (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 46

Slide 46 text

Occurrence Typing (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 47

Slide 47 text

Occurrence Typing (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 48

Slide 48 text

Occurrence Typing (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 49

Slide 49 text

Occurrence Typing (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 50

Slide 50 text

Occurrence Typing (: 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 51

Slide 51 text

Occurrence Typing (: 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 52

Slide 52 text

Occurrence Typing (: 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 53

Slide 53 text

Occurrence Typing (: 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 54

Slide 54 text

Occurrence Typing (: 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 55

Slide 55 text

Building on Existing Languages

Slide 56

Slide 56 text

Languages as Libraries name #lang typed/racket ....

Slide 57

Slide 57 text

Languages as Libraries (module name typed/racket (#%module-begin ....) )

Slide 58

Slide 58 text

Languages as Libraries typed/racket #lang racket (define-syntax (#%module-begin stx) ....) (module name typed/racket (#%module-begin ....) ) #%module-begin #%module-begin

Slide 59

Slide 59 text

Defining A Language (define-syntax (#%module-begin stx) (syntax-parse stx [(_ forms ...) (let () (for ([f (syntax->list #'(forms ...))]) (typecheck f)) #'(#%plain-module-begin forms ...))]))

Slide 60

Slide 60 text

Defining A Language (define-syntax (#%module-begin stx) (syntax-parse stx [(_ forms ...) (let () (for ([f (syntax->list #'(forms ...))]) (typecheck f)) #'(#%plain-module-begin forms ...))])) f

Slide 61

Slide 61 text

Defining A Language (define-syntax (#%module-begin stx) (syntax-parse stx [(_ forms ...) (let ([forms* (local-expand #'(forms ...))]) (for ([f (rest (syntax->list forms*))]) (typecheck f)) #'(#%plain-module-begin #,forms*))]))

Slide 62

Slide 62 text

Defining A Language (define-syntax (#%module-begin stx) (syntax-parse stx [(_ forms ...) (let ([forms* (local-expand #'(forms ...))]) (for ([f (rest (syntax->list forms*))]) (typecheck f)) (let ([forms** (optimize forms*)]) #'(#%plain-module-begin #,forms**)))]))

Slide 63

Slide 63 text

Typechecking (define (typecheck f) (syntax-parse f ; variables [v:identifier (lookup-type #'v)] ; abstractions [(lambda (x) e) (define t (syntax-property #'x 'type-label)) (set-type! #'x t) (typecheck #'e)] ; about 10 more cases ....))

Slide 64

Slide 64 text

Typechecking (define (typecheck f) (syntax-parse f ; variables [v:identifier (lookup-type #'v)] ; abstractions [(lambda (x) e) (define t (syntax-property #'x 'type-label)) (set-type! #'x t) (typecheck #'e)] ; about 10 more cases ....))

Slide 65

Slide 65 text

Typechecking (define (typecheck f) (syntax-parse f ; variables [v:identifier (lookup-type #'v)] ; abstractions [(lambda (x) e) (define t (syntax-property #'x 'type-label)) (set-type! #'x t) (typecheck #'e)] ; about 10 more cases ....))

Slide 66

Slide 66 text

Optimization #lang typed/racket (: norm : Float Float -> Float) (define (norm x y) (flsqrt (+ (* x x) (* y y))))

Slide 67

Slide 67 text

Optimization #lang typed/racket (: norm : Float Float -> Float) (define (norm x y) (unsafe-flsqrt (unsafe-fl+ (unsafe-fl* x x) (unsafe-fl* y y))))

Slide 68

Slide 68 text

Typed Racket as Research Agenda

Slide 69

Slide 69 text

Contracts (Vectorof (Integer -> Integer)) (class/c ....) (unit/c ....) Analysis using contracts With Stevie Strickland, Robby Findler, Matthew Flatt, David Van Horn

Slide 70

Slide 70 text

Types First-class Classes Generic Operations Variable-Arity Functions .... and Inference With Stevie Strickland, Asumu Takikawa, Matthias Felleisen

Slide 71

Slide 71 text

Macros syntax-parse Macro Debugging Defensible Abstractions With Ryan Culpepper

Slide 72

Slide 72 text

Education Beginner-Level Error Messages #lang typed/racket (first 3) Type Checker: Polymorphic function first could not be applied to arguments: Domains: (Pairof a (Listof b)) (Listof a) Arguments: Positive-Fixnum With Eli Barzilay, Matthias Felleisen

Slide 73

Slide 73 text

Optimization Low-Level Operations for • Structure Representation • Memory Allocation • ... With Vincent St-Amour, Matthew Flatt

Slide 74

Slide 74 text

Jesse Tov Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 75

Slide 75 text

Jesse Tov Felix Klock Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 76

Slide 76 text

Jesse Tov Felix Klock Eli Barzilay Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 77

Slide 77 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 78

Slide 78 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 79

Slide 79 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 80

Slide 80 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 81

Slide 81 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 82

Slide 82 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 83

Slide 83 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 84

Slide 84 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 85

Slide 85 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 86

Slide 86 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 87

Slide 87 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 88

Slide 88 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Matthias Felleisen Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 89

Slide 89 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Matthias Felleisen Vincent St-Amour Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 90

Slide 90 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Matthias Felleisen Vincent St-Amour Shriram Krishnamurthi Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 91

Slide 91 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Matthias Felleisen Vincent St-Amour Shriram Krishnamurthi Students at Northeastern and Brown Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 92

Slide 92 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Matthias Felleisen Vincent St-Amour Shriram Krishnamurthi Students at Northeastern and Brown And everyone who has tried Typed Racket! Thanks! Available from racket-lang.org Supported by the Mozilla Foundation

Slide 93

Slide 93 text

Jesse Tov Felix Klock Eli Barzilay Ivan Gazeau Neil Toronto Aaron Turon Carl Eastlund Robby Findler Jay McCarthy Matthew Flatt Hari Prashanth Ryan Culpepper David Van Horn Stevie Strickland Matthias Felleisen Vincent St-Amour Shriram Krishnamurthi Students at Northeastern and Brown And everyone who has tried Typed Racket! Thanks! Available from racket-lang.org Supported by the Mozilla Foundation