Typing the Numeric Tower Vincent St-Amour, Sam Tobin-Hochstadt, - - PowerPoint PPT Presentation

typing the numeric tower
SMART_READER_LITE
LIVE PREVIEW

Typing the Numeric Tower Vincent St-Amour, Sam Tobin-Hochstadt, - - PowerPoint PPT Presentation

Typing the Numeric Tower Vincent St-Amour, Sam Tobin-Hochstadt, Matthew Flatt, Matthias Felleisen PLT PADL 2012 - January 24th, 2012 Approaches to numerics Traditional Java, C(++), Fortran, ... Type Classes Haskell, Clean, ...


slide-1
SLIDE 1

Typing the Numeric Tower

Vincent St-Amour, Sam Tobin-Hochstadt, Matthew Flatt, Matthias Felleisen PLT

PADL 2012 - January 24th, 2012

slide-2
SLIDE 2
slide-3
SLIDE 3

Approaches to numerics

  • Traditional

Java, C(++), Fortran, ...

  • Type Classes

Haskell, Clean, ...

  • Numeric Tower

Racket, Scheme, Smalltalk, ...

slide-4
SLIDE 4

Approaches to numerics

  • Traditional

Java, C(++), Fortran, ...

  • Type Classes

Haskell, Clean, ...

  • Numeric Tower

Racket, Scheme, Smalltalk, ...

slide-5
SLIDE 5

Approaches to numerics

  • Traditional

Java, C(++), Fortran, ...

  • Type Classes

Haskell, Clean, ...

  • Numeric Tower

Racket, Scheme, Smalltalk, ...}

Typed Numeric Tower

Typed Racket

slide-6
SLIDE 6

Our criteria

  • Ease of expression
  • Domain fidelity
  • Static checking
  • Performance
slide-7
SLIDE 7

Our benchmarks

slide-8
SLIDE 8

Type Classes

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p))

slide-9
SLIDE 9

Type Classes

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p)) genRandom 2.3 7.4

  • - => 2.3016764082953687
slide-10
SLIDE 10

Type Classes

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p)) genRandom 2.3 7.4

  • - => 2.3016764082953687

genRandom (toRational 2) (toRational 7)

  • - => 9927678409 % 2147483647
slide-11
SLIDE 11

Type Classes

Ease of expression

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p)) genRandom 2.3 7.4

  • - => 2.3016764082953687

genRandom (toRational 2) (toRational 7)

  • - => 9927678409 % 2147483647
slide-12
SLIDE 12

Type Classes

Ease of expression Domain fidelity

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p)) genRandom 2.3 7.4

  • - => 2.3016764082953687

genRandom (toRational 2) (toRational 7)

  • - => 9927678409 % 2147483647
slide-13
SLIDE 13

Type Classes

Ease of expression Domain fidelity Static checking

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p)) genRandom 2.3 7.4

  • - => 2.3016764082953687

genRandom (toRational 2) (toRational 7)

  • - => 9927678409 % 2147483647
slide-14
SLIDE 14

Type Classes

Ease of expression Domain fidelity Static checking Performance

p = (2^31) - 1 a = 7^5 x = unsafePerformIO $ newIORef 42 genRandom min max = do old <- readIORef x writeIORef x (mod (a * old) p) new <- readIORef x return $ min + (((max-min) * (fromInteger new)) / (fromInteger p)) genRandom 2.3 7.4

  • - => 2.3016764082953687

genRandom (toRational 2) (toRational 7)

  • - => 9927678409 % 2147483647
slide-15
SLIDE 15

Numeric Tower

(define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p)))

slide-16
SLIDE 16

Numeric Tower

(define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p))) (gen-random 2.3 7.4) ; => 2.3016764082953687

slide-17
SLIDE 17

Numeric Tower

(define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p))) (gen-random 2.3 7.4) ; => 2.3016764082953687 (gen-random 2 7) ; => 9927678409/2147483647

slide-18
SLIDE 18

Numeric Tower

Ease of expression (define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p))) (gen-random 2.3 7.4) ; => 2.3016764082953687 (gen-random 2 7) ; => 9927678409/2147483647

slide-19
SLIDE 19

Numeric Tower

Ease of expression Domain fidelity (define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p))) (gen-random 2.3 7.4) ; => 2.3016764082953687 (gen-random 2 7) ; => 9927678409/2147483647

slide-20
SLIDE 20

Numeric Tower

Ease of expression Domain fidelity Static checking (define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p))) (gen-random 2.3 7.4) ; => 2.3016764082953687 (gen-random 2 7) ; => 9927678409/2147483647

slide-21
SLIDE 21

Numeric Tower

Ease of expression Domain fidelity Static checking Performance (define p (- (expt 2 31) 1)) (define A (expt 7 5)) (define x 42) ; state of the PRNG (define (gen-random min max) (set! x (modulo (* A x) p)) (+ min (/ (* (- max min) x) p))) (gen-random 2.3 7.4) ; => 2.3016764082953687 (gen-random 2 7) ; => 9927678409/2147483647

slide-22
SLIDE 22

Type Classes

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a)

slide-23
SLIDE 23

Type Classes

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124
slide-24
SLIDE 24

Type Classes

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124

q (fromInteger 1) (fromInteger 3) (fromInteger (-4))

  • - => 1.0
slide-25
SLIDE 25

Type Classes

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124

q (fromInteger 1) (fromInteger 3) (fromInteger (-4))

  • - => 1.0

q (fromInteger 1) (fromInteger 3) (fromInteger 3)

  • - => NaN
slide-26
SLIDE 26

Type Classes

Ease of expression

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124

q (fromInteger 1) (fromInteger 3) (fromInteger (-4))

  • - => 1.0

q (fromInteger 1) (fromInteger 3) (fromInteger 3)

  • - => NaN
slide-27
SLIDE 27

Type Classes

Ease of expression Domain fidelity

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124

q (fromInteger 1) (fromInteger 3) (fromInteger (-4))

  • - => 1.0

q (fromInteger 1) (fromInteger 3) (fromInteger 3)

  • - => NaN
slide-28
SLIDE 28

Type Classes

Ease of expression Domain fidelity Static checking

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124

q (fromInteger 1) (fromInteger 3) (fromInteger (-4))

  • - => 1.0

q (fromInteger 1) (fromInteger 3) (fromInteger 3)

  • - => NaN
slide-29
SLIDE 29

Type Classes

Ease of expression Domain fidelity Static checking Performance

q :: (Floating a) => a -> a -> a -> a q a b c = (-b + sqrt (b**2 - 4*a*c)) / (2*a) q 2.4 36.2 (-7.5)

  • - => 0.20441209042786124

q (fromInteger 1) (fromInteger 3) (fromInteger (-4))

  • - => 1.0

q (fromInteger 1) (fromInteger 3) (fromInteger 3)

  • - => NaN
slide-30
SLIDE 30

Numeric Tower

(define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a)))

slide-31
SLIDE 31

Numeric Tower

(define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124

slide-32
SLIDE 32

Numeric Tower

(define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124 (q 1 3 -4) ; => 1 ; =>

slide-33
SLIDE 33

Numeric Tower

(define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124 (q 1 3 -4) ; => 1 ; => (q 1 3 3) ; => -1.5+0.8660254037844386i ; =>

slide-34
SLIDE 34

Numeric Tower

Ease of expression (define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124 (q 1 3 -4) ; => 1 ; => (q 1 3 3) ; => -1.5+0.8660254037844386i ; =>

slide-35
SLIDE 35

Numeric Tower

Ease of expression Domain fidelity (define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124 (q 1 3 -4) ; => 1 ; => (q 1 3 3) ; => -1.5+0.8660254037844386i ; =>

slide-36
SLIDE 36

Numeric Tower

Ease of expression Domain fidelity Static checking (define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124 (q 1 3 -4) ; => 1 ; => (q 1 3 3) ; => -1.5+0.8660254037844386i ; =>

slide-37
SLIDE 37

Numeric Tower

Ease of expression Domain fidelity Static checking Performance (define (q a b c) (/ (+ (- b) (sqrt (- (sqr b) (* 4 a c)))) (* 2 a))) (q 2.4 36.2 -7.5) ; => 0.20441209042786124 (q 1 3 -4) ; => 1 ; => (q 1 3 3) ; => -1.5+0.8660254037844386i ; =>

slide-38
SLIDE 38

Type Classes Numeric Tower

Ease of expression Domain fidelity Static checking Performance PRNG Quad PRNG Quad

slide-39
SLIDE 39

Type Classes Numeric Tower Typed Numeric Tower

Ease of expression Domain fidelity Static checking Performance PRNG Quad PRNG Quad All programs

slide-40
SLIDE 40

Typed Numeric Tower

Ease of expression Domain fidelity Static checking Performance

slide-41
SLIDE 41

Typed Numeric Tower

Ease of expression Domain fidelity Static checking Powerful type system Performance

slide-42
SLIDE 42

Typed Numeric Tower

Ease of expression Domain fidelity Static checking Powerful type system Performance Type-driven optimization

slide-43
SLIDE 43

The Type System

  • Union types
  • Function intersection types
  • Occurrence typing
slide-44
SLIDE 44

Union types

302 : Integer 302 : (U Integer Float) 3.2 : (U Integer Float)

slide-45
SLIDE 45

Union types

302 : Integer 302 : (U Integer Float) 3.2 : (U Integer Float)

  • No injections! No projections!
slide-46
SLIDE 46

Union types

302 : Integer 302 : (U Integer Float) 3.2 : (U Integer Float)

  • No injections! No projections!

Ease of Expression

slide-47
SLIDE 47

Union types

302 : Integer 302 : (U Integer Float) 3.2 : (U Integer Float)

  • No injections! No projections!

Ease of Expression

  • No tags!

23.2 : Positive-Float

  • 3.2 : Negative-Float
slide-48
SLIDE 48

Union types

302 : Integer 302 : (U Integer Float) 3.2 : (U Integer Float)

  • No injections! No projections!

Ease of Expression

  • No tags!

23.2 : Positive-Float

  • 3.2 : Negative-Float

Representation independence Performance

slide-49
SLIDE 49

Union types

slide-50
SLIDE 50

Union types

slide-51
SLIDE 51

Union types

slide-52
SLIDE 52

Union types

slide-53
SLIDE 53

Union types

slide-54
SLIDE 54

Union types

slide-55
SLIDE 55

Union types

Performance

slide-56
SLIDE 56

Function intersection types

(: f (case→ (Number → Number) (String → Number)))

slide-57
SLIDE 57

Function intersection types

(: f (case→ (Number → Number) (String → Number))) (define (f x) 0)

slide-58
SLIDE 58

Function intersection types

(: f (case→ (Number → Number) (String → Number))) (define (f x) 0) Representation independence Performance

slide-59
SLIDE 59

Function intersection types

(: + (case→ (Integer Integer → Integer) (Float Float → Float) ... (Number Number → Number)))

slide-60
SLIDE 60

Function intersection types

(: + (case→ (Integer Integer → Integer) (Float Float → Float) (Integer Float → Float) ... (Number Number → Number)))

slide-61
SLIDE 61

Function intersection types

(: + (case→ (Integer Integer → Integer) (Float Float → Float) (Integer Float → Float) ... (Number Number → Number))) Ease of expression (* (- max min) x)

slide-62
SLIDE 62

Function intersection types

(: + (case→ (Integer Integer → Integer) (Float Float → Float) (Integer Float → Float) ... (Number Number → Number))) Ease of expression (* (- max min) x) (: sqrt (case→ (Nonnegative-Real → Nonnegative-Real) (Real → Complex) ...))

slide-63
SLIDE 63

Function intersection types

(: + (case→ (Integer Integer → Integer) (Float Float → Float) (Integer Float → Float) ... (Number Number → Number))) Ease of expression (* (- max min) x) (: sqrt (case→ (Nonnegative-Real → Nonnegative-Real) (Real → Complex) ...)) Domain fidelity (q 1 3 3) ; => -1.5+0.8660254037844386i

slide-64
SLIDE 64

Occurrence typing

(: abs : Real → Nonnegative-Real) (define (abs x) (if (> x 0) x (- x)))

slide-65
SLIDE 65

Occurrence typing

(: abs : Real → Nonnegative-Real) (define (abs x) (if (> x 0) x (- x)))

slide-66
SLIDE 66

Occurrence typing

(: abs : Real → Nonnegative-Real) (define (abs x) (if (> x 0) x (- x))) Ease of expression

slide-67
SLIDE 67

Type-driven optimization

  • Arithmetic specialization
  • Unboxing
  • Arity raising of complex numbers
  • ...
slide-68
SLIDE 68

Type-driven optimization

  • Arithmetic specialization
  • Unboxing
  • Arity raising of complex numbers
  • ...

Mostly standard

slide-69
SLIDE 69

Type-driven optimization

  • Arithmetic specialization
  • Unboxing
  • Arity raising of complex numbers
  • ...

Mostly standard

Representation independence Positive-Float <: Float

slide-70
SLIDE 70

Smaller is better

slide-71
SLIDE 71

Usability

slide-72
SLIDE 72

> (+ 1 "A") Type Checker: No function domains matched in function application: Domains: Zero Zero Zero Positive-Byte Byte Positive-Byte Byte Byte ... <snip 58 lines> ... Real Real Float-Complex Number Number Float-Complex Number Number Arguments: Positive-Byte String in: (+ 1 "A")

slide-73
SLIDE 73 [+ (from-cases (binop -Zero) (map (lambda (t) (commutative-binop t -Zero t)) (list -One -PosByte -Byte -PosIndex -Index
  • PosFixnum -NonNegFixnum -NegFixnum -NonPosFixnum -Fixnum))
(-> -PosByte -PosByte -PosIndex) (-> -Byte -Byte -Index) (-> -PosByte -PosByte -PosByte -PosIndex) (-> -Byte -Byte -Byte -Index) (commutative-binop -PosIndex -Index -PosFixnum) (-> -PosIndex -Index -Index -PosFixnum) (-> -Index -PosIndex -Index -PosFixnum) (-> -Index -Index -PosIndex -PosFixnum) (-> -Index -Index -NonNegFixnum) (-> -Index -Index -Index -NonNegFixnum) (commutative-binop -NegFixnum -One -NonPosFixnum) (commutative-binop -NonPosFixnum -NonNegFixnum -Fixnum) (commutative-case -PosInt -Nat -PosInt) (commutative-case -NegInt -NonPosInt -NegInt) (map varop (list -Nat -NonPosInt -Int)) (commutative-case -PosRat -NonNegRat -PosRat) (commutative-case -NegRat -NonPosRat -NegRat) (map varop (list -NonNegRat -NonPosRat -Rat)) (commutative-case -PosFlonum -NonNegReal -PosFlonum) (commutative-case -PosReal -NonNegFlonum -PosFlonum) (commutative-case -NegFlonum -NonPosReal -NegFlonum) (commutative-case -NegReal -NonPosFlonum -NegFlonum) (commutative-case -NonNegFlonum -NonNegReal -NonNegFlonum) (commutative-case -NonPosFlonum -NonPosReal -NonPosFlonum) (commutative-case -Flonum -Real -Flonum) (commutative-case -PosSingleFlonum (Un -NonNegRat -NonNegSingleFlonum) -PosSingleFlonum) (commutative-case (Un -PosRat -PosSingleFlonum) -NonNegSingleFlonum -PosSingleFlonum) (commutative-case -NegSingleFlonum (Un -NonPosRat -NonPosSingleFlonum) -NegSingleFlonum) (commutative-case (Un -NegRat -NegSingleFlonum) -NonPosSingleFlonum -NegSingleFlonum) (commutative-case -NonNegSingleFlonum (Un -NonNegRat -NonNegSingleFlonum) -NonNegSingleFlonum) (commutative-case -NonPosSingleFlonum (Un -NonPosRat -NonPosSingleFlonum) -NonPosSingleFlonum) (commutative-case -SingleFlonum (Un -Rat -SingleFlonum) -SingleFlonum) (commutative-case -PosInexactReal -NonNegReal -PosInexactReal) (commutative-case -PosReal -NonNegInexactReal -PosInexactReal) (commutative-case -NegInexactReal -NonPosReal -NegInexactReal) (commutative-case -NegReal -NonPosInexactReal -NegInexactReal) (commutative-case -NonNegInexactReal -NonNegReal -NonNegInexactReal) (commutative-case -NonPosInexactReal -NonPosReal -NonPosInexactReal) (commutative-case -InexactReal -Real -InexactReal) (commutative-case -PosReal -NonNegReal -PosReal) (commutative-case -NegReal -NonPosReal -NegReal) (map varop (list -NonNegReal -NonPosReal -Real -ExactNumber)) (commutative-case -FloatComplex N -FloatComplex) (commutative-case -Flonum -InexactComplex -FloatComplex) (commutative-case -SingleFlonumComplex (Un -Rat -SingleFlonum -SingleFlonumComplex) -SingleFlonumComplex) (commutative-case -InexactComplex (Un -Rat -InexactReal -InexactComplex) -InexactComplex) (varop N))]

56 lines of type DSL 22k of printout

slide-74
SLIDE 74

> (+ 1 "A") Type Checker: No function domains matched in function application: Domains: Number Number Arguments: Positive-Byte String in: (+ 1 "A")

slide-75
SLIDE 75

(define x (box 3))

slide-76
SLIDE 76

(define x (box 3)) : (Boxof Positive-Byte)

slide-77
SLIDE 77

(define x (box 3)) : (Boxof Positive-Byte) (set-box! x 2000)

slide-78
SLIDE 78

(define x (box 3)) : (Boxof Number) (set-box! x 2000)

slide-79
SLIDE 79

(define x (box 3)) : (Boxof Number) (set-box! x 2000) (vector-ref v (unbox x))

slide-80
SLIDE 80

(define x (box 3)) : (Boxof Natural) (set-box! x 2000) (vector-ref v (unbox x))

slide-81
SLIDE 81

Typed Numeric Tower

Ease of expression Domain fidelity Static checking Performance Key type system features

  • Union types
  • Function intersection types
  • Occurrence typing
slide-82
SLIDE 82

Typed Numeric Tower

Ease of expression Domain fidelity Static checking Performance Key type system features

  • Union types
  • Function intersection types
  • Occurrence typing

racket-lang.org