Once Upon a Polymorphic Type CAMBRIDGE Keith Wansbrough Computer - - PowerPoint PPT Presentation

once upon a polymorphic type
SMART_READER_LITE
LIVE PREVIEW

Once Upon a Polymorphic Type CAMBRIDGE Keith Wansbrough Computer - - PowerPoint PPT Presentation

UNIVERSITY OF Once Upon a Polymorphic Type CAMBRIDGE Keith Wansbrough Computer Laboratory University of Cambridge kw217@cl.cam.ac.uk http://www.cl.cam.ac.uk/users/kw217/ Simon Peyton Jones Microsoft Research Cambridge 20 January, 1999


slide-1
SLIDE 1

UNIVERSITY OF

CAMBRIDGE

Once Upon a Polymorphic Type

Keith Wansbrough

Computer Laboratory University of Cambridge kw217@cl.cam.ac.uk http://www.cl.cam.ac.uk/users/kw217/

Simon Peyton Jones

Microsoft Research Cambridge

20 January, 1999

Once Upon a Polymorphic Type (POPL’99) 1 20 January, 1999

slide-2
SLIDE 2

UNIVERSITY OF

CAMBRIDGE

Why usage analysis? Problem:

Lazy evaluation (call-by-need) is useful but slow

Solutions:

Strictness analysis: convert call-by-need to call-by-value Usage analysis: convert call-by-need to call-by-name

Once Upon a Polymorphic Type (POPL’99) 2 20 January, 1999

slide-3
SLIDE 3

UNIVERSITY OF

CAMBRIDGE

Lazy evaluation

let x = 3 + 4 y = 5 + 6 in x + x + y

Heap, before and after:

x : 3 + 4 y : 5 + 6 x : 7 y : 11

unnecessary update Unnecessary updates mean excess memory traffic.

Once Upon a Polymorphic Type (POPL’99) 3 20 January, 1999

slide-4
SLIDE 4

UNIVERSITY OF

CAMBRIDGE

The goal Identify variables and subexpressions that will be evaluated at most once.

Once Upon a Polymorphic Type (POPL’99) 4 20 January, 1999

slide-5
SLIDE 5

UNIVERSITY OF

CAMBRIDGE

Usage analysis enables other optimisations too Inlining:

let x = e in
  • y
: case x
  • f
: : : ! : : :
  • y
: case e
  • f
: : : ! : : :

Here

x occurs in none of the case alternatives. We avoid

constructing a thunk for

x entirely, by inlining e.

Always valid, but serious slow-down if lambda applied more than

  • nce; ‘work-safe’ if lambda applied (used) at most once.

Several other optimisations can similarly benefit from usage information.

Once Upon a Polymorphic Type (POPL’99) 5 20 January, 1999

slide-6
SLIDE 6

UNIVERSITY OF

CAMBRIDGE

Plan of attack

Hask ell source Desugar Core Core-to-Core transforms Usage inference Co de generation C / Assem bler Usage inference

Usage inference provides additional information at Core level to guide optimising transformations and code generation.

Once Upon a Polymorphic Type (POPL’99) 6 20 January, 1999

slide-7
SLIDE 7

UNIVERSITY OF

CAMBRIDGE

How do we do it? It seems that we should simply be able to count syntactic

  • ccurrences. But this is not enough.
let y = 1 + 2 in let f =
  • x
: x + y in f 3 + f 4

Here

y appears once in its scope. But it is used twice, once for each

call to

f.

The usage of

y depends on the usage of f.

Once Upon a Polymorphic Type (POPL’99) 7 20 January, 1999

slide-8
SLIDE 8

UNIVERSITY OF

CAMBRIDGE

Types We represent usage information in the types of expressions:

42 : Int !
  • x
: Int 1 : x : (Int 1 ! Int 1 ) !
  • x
: Int 1 :
  • y
: Int 1 : x + y : (Int 1 ! (Int 1 ! Int ! ) 1 ) ! let x : Int ! = 3 + 4 y : Int 1 = 5 + 6 in x + x + y : Int !

Once Upon a Polymorphic Type (POPL’99) 8 20 January, 1999

slide-9
SLIDE 9

UNIVERSITY OF

CAMBRIDGE

Type syntax Types

  • ::=
T
  • k

(unannotated)

j
  • 1
!
  • 2
j 8 :
  • j
  • Types
  • ::=
  • u

(annotated) Usages

u ::= 1 j !

for example,

  • (List
Int ) 1 ! Int !
  • !.

Once Upon a Polymorphic Type (POPL’99) 9 20 January, 1999

slide-10
SLIDE 10

UNIVERSITY OF

CAMBRIDGE

Type rules Type judgements are of the form

  • `
e :
  • context

expression type For example, the rule for addition:

  • `
e 1 : Int u 1
  • `
e 2 : Int u 2 (`-PrimOp )
  • `
e 1 + e 2 : Int u 3

Once Upon a Polymorphic Type (POPL’99) 10 20 January, 1999

slide-11
SLIDE 11

UNIVERSITY OF

CAMBRIDGE

Type rules for UsageSP – 1: Functions

; x :
  • 1
` e :
  • 2
  • c
cur (x; e) > 1 ) j 1 j = !

(multiple occurrence)

  • c
cur (y ; e) > ) j(y )j
  • u

for all

y 2
  • (free variables)
(`-Abs)
  • `
  • x
:
  • 1
: e : ( 1 !
  • 2
) u
  • c
cur (; ) is defined syntactically. let y : Int ! = 1 + 2 in let f : (Int 1 ! Int 1 ) ! =
  • x
: Int 1 : x + y in f 3 + f 4 : Int !

Here

  • c
cur (x; x + y ) = 1,
  • c
cur (y ; x + y ) = 1,
  • c
cur (f ; f 3 + f 4) = 2.

Once Upon a Polymorphic Type (POPL’99) 11 20 January, 1999

slide-12
SLIDE 12

UNIVERSITY OF

CAMBRIDGE

Three design decisions

Type polymorphism:

– Should type variables be annotated or unannotated? What is the usage of a type abstraction?

Algebraic data structures:

– How should constructor applications be typed?

The poisoning problem:

– How can we avoid equating usages of all arguments to a common function?

Once Upon a Polymorphic Type (POPL’99) 12 20 January, 1999

slide-13
SLIDE 13

UNIVERSITY OF

CAMBRIDGE

Design decision 1: Type polymorphism

Range of type variables:

– Should type arguments be annotated or unannotated?

f : (8 :
  • !
( ! ( ;
  • ;
  • )
1 ) 1 ) !
  • r
f : (8 :
  • 1
! ( ! ! ( ;
  • ;
  • )
1 ) 1 ) !

?

Type of type abstractions:

– Given

  • `
e :
  • u, what is
`
  • :
e : ?

Once Upon a Polymorphic Type (POPL’99) 13 20 January, 1999

slide-14
SLIDE 14

UNIVERSITY OF

CAMBRIDGE

Type rules for UsageSP – 3: Type polymorphism Type abstractions and applications are treated as ‘transparent’ for the purposes of usage annotation, since

  • perationally they have no significance. These rules simply lift and

lower the usage annotation.

;
  • `
e :
  • u
(`-TyAbs)
  • `
  • :
e : (8 :
  • )
u
  • `
e : (8 :
  • 2
) u (`-TyApp)
  • `
e
  • 1
: ( 2 [ :=
  • 1
]) u

Once Upon a Polymorphic Type (POPL’99) 14 20 January, 1999

slide-15
SLIDE 15

UNIVERSITY OF

CAMBRIDGE

Design decision 2: Data structures Our language features user-defined algebraic data types such as

data T r e e
  • =
Br anch (T r e e
  • )
  • (T
r e e
  • )
j L e af
  • How should these be typed?

Once Upon a Polymorphic Type (POPL’99) 15 20 January, 1999

slide-16
SLIDE 16

UNIVERSITY OF

CAMBRIDGE

Data structures: First attempt If we treat data constructors as normal functions, what usages should we place on the arguments and result?

Br anch : 8 : (T r e e
  • )
? ! ( ? ! ((T r e e
  • )
? ! (T r e e
  • )
? ) ? ) ?

To make

Br anch universally applicable, we must set ? = !.

: : :

inaccurate. The usages

? really depend on how the constructed data is used, not
  • n the constructor itself.

Once Upon a Polymorphic Type (POPL’99) 16 20 January, 1999

slide-17
SLIDE 17

UNIVERSITY OF

CAMBRIDGE

The tantalising opportunity

let f : (Int ! ! (Int ! ! (Int; Int) 1 ) ! ) ! f =
  • x
: Int ! :
  • y
: Int ! : let p = : : : q = : : : in (p; q ) in case f x y
  • f
(p; q ) ! p + q

Each component of the pair returned by

f is used only once. Hence p and q need not be updated on evaluation.

How can we propagate this information from the usage site (the

case

expression) to the construction site in

f?

Once Upon a Polymorphic Type (POPL’99) 17 20 January, 1999

slide-18
SLIDE 18

UNIVERSITY OF

CAMBRIDGE

Data structure usage propagation – 1 We propagate usage information through the type of the constructed data. There are a number of alternatives here.

data Pair
  • =
(; )
  • data
T r e e
  • =
Br anch (T r e e
  • )
  • (T
r e e
  • )
j L e af
  • 1. Give usage annotations for each constructor argument explicitly

in the type:

(; ) 1 1 Int Int 3 4 Br anch ! 1 ! 1 Int t 1 3 t 2

(typical application)

((; ) Int 1 Int 1 ) u (Br anch (T r e e ! 1 ! 1 Int) ! Int 1 (T r e e ! 1 ! 1 Int) ! ) u j (L e af Int 1 ) u

(effective type) This is the most general approach, but it is expensive.

Once Upon a Polymorphic Type (POPL’99) 18 20 January, 1999

slide-19
SLIDE 19

UNIVERSITY OF

CAMBRIDGE

Data structure usage propagation – 2

  • 2. Attach usage annotations to each type argument [BS96]:
(; ) Int 1 Int 1 3 4 Br anch Int 1 t 1 3 t 2 ((; ) Int 1 Int 1 ) u (Br anch (T r e e Int 1 ) ? Int 1 (T r e e Int 1 ) ? ) u j (L e af Int 1 ) u
  • 3. Assume all constructor arguments will be used more than once.
(; ) Int Int 3 4 Br anch Int t 1 3 t 2 ((; ) Int ! Int ! ) u (Br anch (T r e e Int) ! Int ! (T r e e Int) ! ) u j (L e af Int ! ) u

Once Upon a Polymorphic Type (POPL’99) 19 20 January, 1999

slide-20
SLIDE 20

UNIVERSITY OF

CAMBRIDGE

Data structure usage propagation – 3

  • 4. Identify usage annotations for each constructor argument with

the overall usage of the constructed data.

(; ) Int Int 3 4 Br anch Int t 1 3 t 2 ((; ) Int u Int u ) u (Br anch (T r e e Int) u Int u (T r e e Int) u ) u j (L e af Int u ) u

We choose this solution because it catches the common cases but costs relatively little in terms of implementation.

Once Upon a Polymorphic Type (POPL’99) 20 20 January, 1999

slide-21
SLIDE 21

UNIVERSITY OF

CAMBRIDGE

Type rules for UsageSP – 4: Data structures

data T
  • k
= C i
  • ij
  • `
e j :
  • ij
  • ij
4 ( ij [ k :=
  • k
]) u

for all

j (`-Con)
  • `
C i
  • k
e j : (T
  • k
) u data T
  • k
= C i
  • ij
  • `
e : (T
  • k
) u
  • `
e i :
  • i
  • i
4 (( ij [ k :=
  • k
]) u !
  • )
1

for all

i (`-Case)
  • `
case e
  • f
C i ! e i :
  • Once Upon a Polymorphic Type (POPL’99)

21 20 January, 1999

slide-22
SLIDE 22

UNIVERSITY OF

CAMBRIDGE

Inference algorithm

  • 1. Annotate program:
(let y : Int u 1 = 1 + 2 in let f : (Int u 2 ! Int u 3 ) u 4 =
  • x
: Int u 5 : x + y in f 3 + f 4) u 6
  • 2. Collect constraints:
fu 4 = ! ; u 4
  • u
1 ; u 5
  • u
2 g
  • 3. Find optimal solution:
fu 1 7! ! ; u 2 7! 1; u 3 7! 1; u 4 7! ! ; u 5 7! 1; u 6 7! 1g A solution always exists (simply set all u i = !). We choose to maximise the number of 1 annotations, calling this

the ‘optimal’ annotation.

Complexity is approx. linear in the size of the (typed) program.

Once Upon a Polymorphic Type (POPL’99) 22 20 January, 1999

slide-23
SLIDE 23

UNIVERSITY OF

CAMBRIDGE

Soundness Claim: Thunks marked

1 are used at most once.

Proof strategy:

  • 1. Provide an operational semantics expressing sharing and

thunks.

  • 2. Ensure evaluation becomes ‘stuck’ if we use a thunk more than
  • nce.
  • 3. Show well-typed programs never become stuck.

Once Upon a Polymorphic Type (POPL’99) 23 20 January, 1999

slide-24
SLIDE 24

UNIVERSITY OF

CAMBRIDGE

Typed operational semantics We base our operational semantics on Launchbury’s natural semantics for lazy evaluation. This semantics is untyped, since types are deleted at runtime (our language does not have a

t yp ecase

construct). However, for the purposes of the proof it is convenient to annotate this semantics with types. Dealing with polymorphism is not straightforward. Since we allow evaluation under a type lambda, it is possible for a

let binding to

create a thunk with a free type variable; if this thunk is na¨ ıvely placed in the heap the type variable becomes unbound. The solution is given in the paper.

Once Upon a Polymorphic Type (POPL’99) 24 20 January, 1999

slide-25
SLIDE 25

UNIVERSITY OF

CAMBRIDGE

Related work

Non-type-based usage analysis:

– Goldberg; Marlow, Gill (GHC)

Type-based usage analysis:

– Linear types (Girard et. al.), affine types (Jacobs et. al.) – Clean (Barendsen et. al.): uniqueness analysis (dual to usage?); subsumption, data types, ML-polymorphism – Turner, Mossin, and Wadler: Once Upon A Type – extended by Mogensen: subsumption, data types – extended by Gustavsson: update markers

Once Upon a Polymorphic Type (POPL’99) 25 20 January, 1999

slide-26
SLIDE 26

UNIVERSITY OF

CAMBRIDGE

Conclusion

The problem: unnecessary updates. The solution: UsageSP : : :

– a type-based analysis – for a realistic language – that is efficiently computable – and has been proven sound.

Once Upon a Polymorphic Type (POPL’99) 26 20 January, 1999

slide-27
SLIDE 27

UNIVERSITY OF

CAMBRIDGE

Future work

Complete the implementation of the analysis in the Glasgow

Haskell Compiler.

Investigate strictness, absence, uniqueness analyses in the

same framework.

Investigate optimisations enabled by the analysis, and prove

‘work-safety’ results for them.

Once Upon a Polymorphic Type (POPL’99) 27 20 January, 1999