A Gradual Typing Poem Sam Tobin-Hochstadt & Robby Finder 1 The - - PowerPoint PPT Presentation

a gradual typing poem
SMART_READER_LITE
LIVE PREVIEW

A Gradual Typing Poem Sam Tobin-Hochstadt & Robby Finder 1 The - - PowerPoint PPT Presentation

A Gradual Typing Poem Sam Tobin-Hochstadt & Robby Finder 1 The Problem Write a function that accepts the specification of an infinite regular tree and turn it into a representation of the tree 2 The Problem Write a function that accepts


slide-1
SLIDE 1

A Gradual Typing Poem

Sam Tobin-Hochstadt & Robby Finder

1

slide-2
SLIDE 2

The Problem

Write a function that accepts the specification of an infinite regular tree and turn it into a representation

  • f the tree

2

slide-3
SLIDE 3

The Problem

Write a function that accepts the specification of an infinite regular tree and turn it into a representation

  • f the tree

Write a function that accepts a tree and finds its period

3

slide-4
SLIDE 4

An Example

4

slide-5
SLIDE 5

An Example Implementation

5

slide-6
SLIDE 6

An Example Implementation

(a (b b c) (c (d d d) (e e c)))

6

slide-7
SLIDE 7

An Example Implementation

(a (b b c) (c (d d d) (e e c)))

Spec

7

slide-8
SLIDE 8

How to Solve It

(a (b b c) (c (d d d) (e e c)))

8

slide-9
SLIDE 9

The Problem with the Solution

The Standard Solution

  • exposes mutability
  • exposes placeholders
  • pushes the burden onto the client (the period

function)

9

slide-10
SLIDE 10

The Problem with the Solution

data STree = STree String STree STree | Link String data ITree = ITree String ITree ITree link :: STree -> ITree link main = conv main where conv :: STree -> ITree conv (STree str tl tr) = ITree str (conv tl) (conv tr) conv (Link str) = find main str [] find :: STree -> String -> [STree] -> ITree find (STree str2 tl tr) str pending | str2==str = conv (STree str2 tl tr) | otherwise = find tl str (tr:pending) find (Link str1) str2 (p:ps) = find p str2 ps period :: ITree -> Maybe Int period (ITree str tl tr) = bfs [(tl,1),(tr,1)] [] where bfs :: [(ITree,Int)] -> [String] -> Maybe Int bfs [] visited = Nothing bfs ((ITree str2 tl tr,i) : rest) visited | str2==str = Just i | elem str2 visited = bfs rest visited | otherwise = bfs (rest ++ [(tl,i+1),(tr,i+1)]) (str2:visited) left :: ITree -> ITree left (ITree str l r) = l right :: ITree -> ITree right (ITree str l r) = r at :: ITree at = link (STree "a" (STree "b" (Link "b") (Link "c")) (STree "c" (STree "d" (Link "d") (Link "d")) (STree "e" (Link "e") (Link "c")))) bt :: ITree bt = left at ct :: ITree ct = right at main :: IO () main = print [period at, period bt, period ct] val exists=List.exists val toString=Int.toString datatype stree=STree of string * stree * stree | Link of string datatype itree=ITree of string * (unit->itree) * (unit->itree) (* link : stree -> itree *) fun link main = let fun conv (STree (str,tl,tr)) = ITree (str,fn () => conv tl,fn () => conv tr) | conv (Link str) = find main str [] and find (STree (str2,tl,tr)) str pending = if (str2=str) then conv (STree (str2,tl,tr)) else find tl str (tr::pending) | find (Link str1) str2 (p::ps) = find p str2 ps in conv main end (* period : ITree -> int option *) fun period (ITree (str,tl,tr)) = let fun elem n l = exists (fn x => (n = x)) l fun bfs [] visited = NONE | bfs ((ITree (str2,tl,tr),i) :: rest) visited = if (str2=str) then SOME i else if (elem str2 visited) then bfs rest visited else bfs (rest @ [(tl(),i+1),(tr(),i+1)]) (str2::visited) in bfs [(tl(),1),(tr(),1)] [] end val at = link (STree ("a",STree("b",Link "b", Link "c"), STree("c",STree("d",Link "d", Link "d"), STree("e",Link "e", Link "c")))) fun left (ITree (st,tl,tr)) = tl() fun right (ITree (st,tl,tr)) = tr() val bt = left at val ct = right at val answers = [period at, period bt, period ct] val change_up = let val r = ref 0 fun f () = (r := !r+1; ITree (toString (!r),f,f)) in ITree("a",f,f) end val exists=List.exists datatype stree = STree of string * stree * stree | Link of string datatype itree = ITree of string * itree option ref * itree option ref (* link : stree -> itree *) fun link main = let val trees = ref [] val tolink = ref [] fun conv (STree (str,tl,tr)) = let val t = ITree (str,conv tl,conv tr) in trees := t :: !trees; ref (SOME t) end | conv (Link str) = let val r = ref NONE in tolink := (r,str) :: !tolink; r end val ans = conv main in app (fn (ITree (str,tl,tr)) => app (fn (r,str2) => if str = str2 then r:=SOME (ITree (str,tl,tr)) else ()) (!tolink)) (!trees); case !ans of SOME x => x end (* period : ITree -> int option *) fun period (ITree (str,ref (SOME tl),ref (SOME tr))) = let fun elem (n:string) l = exists (fn x => (n = x)) l fun help [] visited = NONE | help ((ITree (str2,ref (SOME tl),ref (SOME tr)),i) :: rest visited = if (str2=str) then SOME i else if (elem str2 visited) then help rest visited else help (rest @ [(tl,i+1),(tr,i+1)]) (str2::visited) in help [(tl,0),(tr,0)] [] end val at = link (STree ("a",STree("b",Link "b", Link "c"), STree("c",STree("d",Link "d", Link "d" STree("e",Link "e", Link "c" fun left (ITree (st,ref (SOME tl),ref (SOME tr))) = tl fun right (ITree (st,ref (SOME tl),ref (SOME tr))) = tr val bt = left at val ct = right at val answers = [period at, period bt, period ct]

10

slide-11
SLIDE 11

Problem Statement The Typed Scheme Advantage An Intro to Typed Scheme The First Solution The Second Solution The Moral

11

slide-12
SLIDE 12

Where We’re Going

Typed Scheme allows a simple implementation of the problem where the complexity of the implementation is hidden the client has all the advantages of the original code

12

slide-13
SLIDE 13

Where We’re Going

Typed Scheme allows a simple implementation of the problem where the complexity of the implementation is hidden the client has all the advantages of the original code All because of gradual typing!

13

slide-14
SLIDE 14

Problem Statement The Typed Scheme Advantage An Intro to Typed Scheme The First Solution The Second Solution The Moral

14

slide-15
SLIDE 15

Typed Scheme

#lang typed-scheme (: x Number) (define x 1)

15

slide-16
SLIDE 16

Typed Structs

#lang typed-scheme (define-struct: ImpTree ([name : Symbol] [left : (U ImpTree Symbol)] [right : (U ImpTree Symbol)]))

16

slide-17
SLIDE 17

Occurrence Typing

#lang typed-scheme (if (ImpTree? t) (display (ImpTree-name t)) (display "no name"))

17

slide-18
SLIDE 18

Modules

#lang typed-scheme (: t ImpTree) (define t (make-ImpTree 'a 'x 'y)) (provide t)

18

slide-19
SLIDE 19

Typed/Untyped Integration

#lang scheme (provide t) (define t (make-ImpTree )) contract boundary #lang typed-scheme (require/typed "x.ss" [t ImpTree]) (ImpTree-left t)

19

slide-20
SLIDE 20

Problem Statement The Typed Scheme Advantage An Intro to Typed Scheme The First Solution The Second Solution The Moral

20

slide-21
SLIDE 21

Specification

(define-type-alias SpecTree (Rec ST (U Symbol (List Symbol ST ST))))

21

slide-22
SLIDE 22

Specification

(define-type-alias SpecTree (Rec ST (U Symbol (List Symbol ST ST)))) (define-struct: ImpTree ([name : Symbol] [left : (U ImpTree Symbol)] [right : (U ImpTree Symbol)]) #:mutable)

22

slide-23
SLIDE 23

Client Code

(: period (ImpTree -> (U Number #f))) (define (period it) )

23

slide-24
SLIDE 24

Client Code

(: period (ImpTree -> (U Number #f))) (define (period it) (: bfs ) (define (bfs s v) ) (let ([l (ImpTree-left it)] [r (ImpTree-right it)]) (if (and (ImpTree? l) (ImpTree? r)) (bfs (list (cons l 1) (cons r 1)) '()) (error 'fail))))

24

slide-25
SLIDE 25

Client Code

(: period (ImpTree -> (U Number #f))) (define (period it) (: bfs ) (define (bfs s v) ) (let ([l (ImpTree-left it)] [r (ImpTree-right it)]) (if (and (ImpTree? l) (ImpTree? r)) (bfs (list (cons l 1) (cons r 1)) '()) (error 'fail))))

25

slide-26
SLIDE 26

Client Code

(: bfs ((Listof (Pair ImpTree Number)) (Listof Symbol)

  • > (U Number #f)))

(define (bfs stack visited) (match stack ['() #f] [(cons (cons (struct ImpTree (str2 tl tr)) i) rest) (cond [(eq? str2 (ImpTree-name it)) i] [(memq str2 visited) (bfs rest visited)] [(and (ImpTree? tl) (ImpTree? tr)) (bfs (append rest (list (cons tl (add1 i)) (cons tr (add1 i)))) (cons str2 visited))] [else (error 'fail)])]))

26

slide-27
SLIDE 27

Client Code

Exactly the problem we thought we’d have

27

slide-28
SLIDE 28

Problem Statement The Typed Scheme Advantage An Intro to Typed Scheme The First Solution The Second Solution The Moral

28

slide-29
SLIDE 29

Better Specification

(define-type-alias SpecTree (Rec ST (U Symbol (List Symbol ST ST)))) (define-struct: ImpTree ([name : Symbol] [left : ImpTree] [right : ImpTree]))

29

slide-30
SLIDE 30

Gradual Typing to the Rescue

(require/typed "itree.ss" [struct ImpTree ([name : Symbol] [left : ImpTree] [right : ImpTree])] [link (SpecTree -> ImpTree)])

30

slide-31
SLIDE 31

Client Code

(: period (ImpTree -> (U Number #f))) (define (period it) )

31

slide-32
SLIDE 32

Client Code

(: period (ImpTree -> (U Number #f))) (define (period it) (let ([l (ImpTree-left it)] [r (ImpTree-right it)]) (bfs (list (cons l 1) (cons r 1)) '())))

32

slide-33
SLIDE 33

Client Code

(: bfs ((Listof (Pair ImpTree Number)) (Listof Symbol)

  • > (U Number #f)))

(define (bfs stack visited) (match stack ['() #f] [(cons (cons (struct ImpTree (str2 tl tr)) i) rest) (cond [(eq? str2 (ImpTree-name it)) i] [(memq str2 visited) (bfs rest visited)] [else (bfs (append rest (list (cons tl (add1 i)) (cons tr (add1 i)))) (cons str2 visited))])]))

33

slide-34
SLIDE 34

What Happened?

Typed Scheme automatically synthesized contracts Mutation is hidden

34

slide-35
SLIDE 35

Problem Statement The Typed Scheme Advantage An Intro to Typed Scheme The First Solution The Second Solution The Moral

35

slide-36
SLIDE 36

Moral

Gradual Typing adds expressiveness to typed languages

36

slide-37
SLIDE 37

Thank You

37