Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implementing a Language with Flow-Sensitive and Structural Subtyping on the JVM David J. Pearce and James Noble Victoria University of Wellington.

Similar presentations


Presentation on theme: "Implementing a Language with Flow-Sensitive and Structural Subtyping on the JVM David J. Pearce and James Noble Victoria University of Wellington."— Presentation transcript:

1 Implementing a Language with Flow-Sensitive and Structural Subtyping on the JVM David J. Pearce and James Noble Victoria University of Wellington

2 void buildLabelMap(List bytecodes) { HashMap labels = new HashMap (); int idx = 0 for(Bytecode b : bytecodes) { if(b instanceof Bytecode.Label) { Bytecode.Label lab = (Bytecode.Label) b; labels.put(lab.name, idx); } idx = idx + 1; } def buildLabelMap(bytecodes): labels = {} idx = 0 for b in bytecodes: if type(b) == “Label”: labels[b.name] = idx idx = idx + 1 Python: Java:

3 The Whiley Language Design Goals: –Look and feel of a dynamically typed language –But, still provide static type checking –Simple programming model –Amenable to program verification void buildLabelMap([Bytecode] bytecodes): labels = {} idx = 0 for b in bytecodes: if b ~= Label: labels[b.name] = idx idx = idx + 1 Whiley:

4 The Whiley Language Design Goals: –Look and feel of a dynamically typed language –But, still provide static type checking –Simple programming model –Amenable to program verification void buildLabelMap([Bytecode] bytecodes): labels = {} idx = 0 for b in bytecodes: if b ~= Label: labels[b.name] = idx idx = idx + 1 Whiley:

5 The Whiley Language Design Goals: –Look and feel of a dynamically typed language –But, still provide static type checking –Simple programming model –Amenable to program verification void buildLabelMap([Bytecode] bytecodes): labels = {} idx = 0 for b in bytecodes: if b ~= Label: labels[b.name] = idx idx = idx + 1 Whiley:

6 Union Types Union types have many uses –Such as neatly handling null references –Or, combining different kinds (i.e. union s of struct s) null|int indexOf(string str, char c): … [string] split(string str, char c): idx = indexOf(str,c) if idx ~= int: below = str[0..idx] above = str[idx..] return [below,above] else: return [str]

7 Union Types Union types have many uses –Such as neatly handling null references –Or, combining different kinds (i.e. union s of struct s) null|int indexOf(string str, char c): … [string] split(string str, char c): idx = indexOf(str,c) if idx ~= int: below = str[0..idx] above = str[idx..] return [below,above] else: return [str]

8 Structural Subtyping Defined types are not nominal –i.e. LinkedList is just a name that “expands” define LinkedList as null | {int dat, LinkedList nxt} define NonEmptyList as {int dat, LinkedList nxt} int sum(LinkedList l): if !(l ~= NonEmptyList): return 0 else: return l.dat + sum(l.nxt) void main([string] args): l={dat: 1, nxt: null} l={dat: 2, nxt: l} out->println(sum(l))

9 Structural Subtyping Defined types are not nominal –i.e. LinkedList is just a name that “expands” define LinkedList as null | {int dat, LinkedList nxt} define NonEmptyList as {int dat, LinkedList nxt} int sum(LinkedList l): if l ~= NonEmptyList: return 0 else: return l.dat + sum(l.nxt) void main([string] args): l={dat: 1, nxt: null} // l->{int dat, null nxt} l={dat: 2, nxt: l} // l->{int dat, {int dat, null nxt} nxt}} out->println(sum(l))

10 Implementation

11 Numbers Unbounded Integers & Rationals –How to implement efficiently on JVM? 1)BigInteger and BigRational 2)SmallInt, BigInt and BigRational [Clojure & Erjang] 3)int[] Adding 100,000 random (small) ints –BigInteger(11ms), SmallInt/BigInt (1ms), int[] (1ms) real weird(real x, [int] map): if x ~= int: // convert x to int x = map[x] // convert x back to real return x

12 Records HashMap implementation: –Map field names to objects –Record access are HashMap lookups Array implementation –Fields allocated to array elements –Faster lookup times –Problem with width subtyping of records define Point as {int x, int y} define Point3D as {int x, int y, int z} int weird(Point p): return p.x + p.y int alsoWierd(Point3D p3d): return weird(p3d) “x” 12 “y” 3

13 Runtime Type Tests Type testing without names is difficult! –Elements may require recursive type test void f([real] xs): if xs ~= [int]: … else: … void f(List xs): for(Object _x : xs) { Number x = (Number) x; if(!x.isInteger()) { goto elseLab; } } … return elseLab: … return

14 Type Testing Records Type testing records == checking for fields –Can do better than brute-force “check all” approach –Test smallest set of “uniquely identifying” fields define Point as {int x, int y} define Point3D as {int x, int y, int z} int weird(Point p): if p ~= Point3D: … else: …

15 Testing Recursive Types Recursive types are also awkward –Must recursively check every node –Potentially expensive – like for lists define LinkedList as {int data, LinkedList y} define WeirdList as {null|int data, WeirdList y} int weird(WeirdList p): if p ~= LinedList: … else: …

16 JVM not fully flow-sensitive!!! JVM uses flow-sensitive typing algorithm –Doesn’t account for instanceof tests –Have to insert casts to keep verifier happy define nstring as null|string int length(nstring ns): if ns ~= string: return |ns| else: return 0 0: aload_0 1: dup 2: instanceof java/util/List 3: ifeq… 4: checkcast java/util/List 5: invokeinterface size()I 6: …

17 Cloning Data types have value semantics: –i.e. lists are not references (as in Java) –E.g. must “clone” lists on assignment –This is inefficient – want to reduce number of clones –E.g. 28125 clones in Chess benchmark (508LOC) void System::main([string] args): xs = [1,2,3] ys = xs // clone required ys[0] = 2 out->println(str(xs)) out->println(str(ys))

18 Conclusion Design Goals: –Look and feel of a dynamically typed language –But, still provide static type checking Implementation on JVM –Efficient representation of integers / rationals –Efficient representation of records –Efficient type testing … ? –Efficient value semantics … ?

19 http://whiley.org


Download ppt "Implementing a Language with Flow-Sensitive and Structural Subtyping on the JVM David J. Pearce and James Noble Victoria University of Wellington."

Similar presentations


Ads by Google