Adoption and Focus: Practical Linear Types for Imperative Programming - PowerPoint PPT Presentation

1 / 24
About This Presentation
Title:

Adoption and Focus: Practical Linear Types for Imperative Programming

Description:

From the previous paper, we have tracked types, and guarded types. Tracked types have the most onerous constraint, that they do not have aliasing. ... – PowerPoint PPT presentation

Number of Views:33
Avg rating:3.0/5.0
Slides: 25
Provided by: scie5
Category:

less

Transcript and Presenter's Notes

Title: Adoption and Focus: Practical Linear Types for Imperative Programming


1
Adoption and Focus Practical Linear Types for
Imperative Programming
  • Manuel Fahndrich and Robert DeLine

2
From before
  • From the previous paper, we have tracked types,
    and guarded types.
  • Tracked types have the most onerous constraint,
    that they do not have aliasing.
  • The type uniquely defines the object it
    represents.
  • Guarded types simply limit the lifetime of an
    object to the lifetime of some tracked type.
  • Guarded types allow for aliasing, within the
    tracked type they are bounded by. Thus, two
    references whose types differ only in their guard
    cannot alias each other. However, if the guard
    type is the same, they may alias each other.

3
More flexible linear types
  • Tracked types correspond to linear types, in that
    there can be only one object associated with the
    type
  • Because of this, Vault is unable to put the
    tracked (linear) types into a container
  • Solution convert tracked types to guarded types,
    when additional flexibility is required

4
Type language
5
Conversion problems
  • Guarded types need a key to guard them
  • - Ask the programmer for a key at demotion
  • Guarded types allow aliasing, which can witness
    behaviors not allowed in tracked types
  • - Abstract the tracked components the
    untracked components might have been aliased
    already, so we dont need to worry about them

6
Adoption
  • Demoting an object corresponds to adoption
  • The programmer supplies an object of tracked
    type, tr(K), which inherits the tracked type we
    are demoting
  • The guard on the demoted type is the key of the
    adopting object
  • The types of the tracked components are changed,
    to indicate they are not presently accessible

7
Adoption rule
8
Focus
  • Converts abstract type to concrete type, for data
    manipulation
  • Of course, it has to be tracked again
  • However, we have all these aliases floating
    around, and we need to prevent access to the
    aliases when we have the tracked type available
  • Use guarded aspect of aliases revoke capability
    to access aliases for the duration of access to
    the tracked type

9
Focus rule
10
Example
  • Dictionary with two indexes to access growable
    arrays
  • fun dict_lookup(phoneint, ssnint, ddictionary)
  • let c newCell(d) in
  • fun add_amount(cellrefltintgt, elemint)
  • resize(cell, newsize)
  • fun add_entry(ddictionary, phoneint, ssnint,
    amountint)
  • let cell dict_lookup(phone, ssn, d)
  • in
  • add_amount(cell, amount)

11
Example
  • Traditional linear typing doesnt work
  • We want the growable arrays to be linear, so that
    we can be sure there are no other dangling
    references after we grow them
  • But, the array is contained in a ref cell, that
    is shared between the two indexes
  • Traditional linear typing would require the
    arrays linear type extend to the ref cell, but
    the ref cell, by design must be aliased

12
newCell
  • fun newCell(dct tr(?d)) ?d B ltintgt
  • pre ?d ? dictionary
  • post ?d ? dictionary
  • let cell tr(?) new lt1gt in
  • cell.1 newarray(10)
  • adopt cell ltintgt by dct

13
Tracked-update
  • After new, capability set is
  • ?d ? dictionary, ? ? hinti
  • Applying the t-update rule, we get
  • ?d ? dictionary, ? ? hint i

14
Adoption
  • Key set before adoption
  • ?d ? dictionary, ? ? hint i
  • Recall code adopt cellh int i by dct
  • Key set after adoption
  • ?d ? dictionary
  • The type of the expression is ?d B h int i

15
resize
  • fun resize?d(cell?d B ltintgt, sizeint) int
  • pre ?d ? dictionary
  • post ?d ? dictionary
  • let newa newarray(size) in
  • let fcell focus cell in
  • let olda fcell.1 in
  • copy(olda, newa)
  • fcell.1 newa
  • free olda

16
focusing
  • Just before the focus, the capabilities are
  • ?d ? dictionary ?1 ? int
  • At the start of the focus body, capabilities are
  • ? ? h int i ?1 ? int
  • Any use of an object guarded by ?d would become a
    type error in the body of the focus

17
T-index
  • let olda fcell.1 in
  • C ? ? h int i ?1 ? int
  • However, t-index cannot return a linear type, so
    we must unpack the capability to convert it into
    a tracked type
  • cap-transform
  • ? ? h int i ? ? h tr(?2)i ?2 ? int
  • So capability set is now
  • ? ? h tr(?2)i ?2 ? int ?1 ? int
  • Apply t-index, to access the tracked array.
  • olda has type tr(?2)

18
T-update
  • copy(olda, newa)
  • fcell.1 newa
  • Copy takes in two tracked arrays, and does the
    copy. No type effects.
  • The t-update rule has already been seen. It
    simply changes the type of the named field. Not
    a null operation, because it is a tracked type,
    so we update the keys
  • Capabilities after
  • ? ? h tr(?1)i ?2 ? int ?1 ? int

19
free
  • free olda
  • Capabilities ? ? h tr(?1)i ?2 ? int
    ?1 ? int
  • Recall olda has type tr(?2)
  • New capability set
  • ? ? h tr(?1)i ?1 ? int

20
End focus
  • Now, we return to end the focus rule
  • Capabilities are ? ? h tr(?1)i ?1 ? int
  • But we need \rho to have the same type as it did
    at the beginning
  • We unpacked before, so pack
  • ? ? h tr(?1) i ?1 ? int ? ? h
    int i
  • C3 is empty, so our final capability set is
  • ?d ? dictionary

21
resize
  • fun resize?d(cell?d B ltintgt, sizeint) int
  • pre ?d ? dictionary
  • post ?d ? dictionary
  • let newa newarray(size) in
  • let fcell focus cell in
  • let olda fcell.1 in
  • copy(olda, newa)
  • fcell.1 newa
  • free olda

22
Whats bad
  • Its hard (inefficient) to write a compare
    function, to check if two arrays are identical
    based on keys
  • Cannot have a reference to two arrays in the
    dictionary
  • Solution get a reference to one array, copy it,
    release the original array. Now open a second
    array, and compare against the copy
  • This is twice as much work as would be required
    without linear types

23
Comparing guarded arrays
  • fun compare(a?d B h int i,
  • b ?d B h int i ,
    sizeint)
  • pre ?d ? dictionary
  • post ?d ? dictionary
  • let newa newarrray(size) in
  • let result
  • (let fcell focus a in
  • let a fcell.1 in
  • copy(a, newa)
  • (let fcell focus b in
  • let b fcell.1 in
  • compare_array(newa, b))) in
  • free(newa)
  • result

A read-only focus would allow the obvious
implementation to work, but would require
functions to have an annotation on whether they
update any values. Its unclear if this
annotation can be checked automatically, thus it
may be error-prone.
24
Operational view
  • When an object is adopted, it gets put into the
    adopted set of the new parent.
  • When the parent is freed, its adopted children
    are linear once again
  • The simplest semantic is to recursively free all
    the children
  • Could also provide a callback function, which
    would know how to return the object t
Write a Comment
User Comments (0)
About PowerShow.com