290 likes | 415 Views
Designing Programming Languages to Improve Software Quality David J. Pearce Software Quality New Zealand, August 2013 @whileydave http:// whiley.org http://github.com/DavePearce. Null Pointers. “ I call it my billion-dollar mistake. It was the invention of the null reference in 1965 ”
E N D
Designing Programming Languages to Improve Software Quality David J. Pearce Software Quality New Zealand, August 2013 @whileydave http://whiley.org http://github.com/DavePearce
Null Pointers “I call it my billion-dollar mistake. It was the invention of the null reference in 1965” -- Tony Hoare “Of all the exceptions a Java programmer might encounter, the null-pointer exception is among the most dreaded, and for good reason: it is one of the least informative exceptions that a program can signal.” -- Eric Allen
Experiences with Null Pointers /** * … * @throws NullPointerException if sb is * null */ boolean contentEquals(StringBuffer sb) { synchronized(sb) { … } } (from java/lang/String.java)
/** * Tests if this string starts with the * specified prefix. * * @param prefix the prefix. * @return true if the character sequence… */ public boolean startsWith(String prefix) { … char pa[] = prefix.value; … } (also from java/lang/String.java)
/** * Tests if this string starts with the * specified prefix. * * @param prefix the prefix. * @return true if the character sequence… */ public boolean startsWith(String prefix) { … char pa[] = prefix.value; … } Found 83/1101 java.lang methods were misdocumented!
Thoughts • Why is documentation bad? • Because programmers write it • Programmers have deadlines • Documentation doesn’t help meet deadlines • When is documentation notbad? • Think about types in Java • Method types automatically documented! • Compiler ensures they are accurate
@NonNull Types void f(@NonNull Integer x) { x.toString(); // safe! } void g(Integer x) { x.toString(); // Syntax Error } void h(Integer x) { if(x != null) { x.toString(); // Safe! } }
JML Specifications public class IntVec { private int data[]; private int length = 0; //@ invariant data != null; //@ invariant length >= 0; //@ invariant length <= data.length; //@ requires size > 0; public IntVec(intsize) { data = new int[size]; } //@ ensures \result >= 0; public int size() { return length; } …
More JML Specifications /*@ public normal_behavior @ requires s1 != null && s2 != null; @ {| @ requires s2.length==0 && s1.length==0; ensures !\result; … @ ensures \result == ( @ (\exists int i; 0<=i && i<s1.length && i<s2.length; @ s1[i]<s2[i] && equal(s1,0,s2,0,i)) @ || @ (s1.length<s2.length && equal(s1,0,s2,0,s1.length))); @ |} @*/ public static pure model boolean lessThan(char[] s1, char[] s2); (from JML spec of java/lang/String.java)
So … ? • PROBLEM: modern languages make compile-time verification unnecessarily hard… • ANSWER: design a language to simplify verification: • Pure Functions vs Impure Methods • Value Semantics • Structural subtyping & Flow Typing • Unbound Integers and Rationals • First-class Collections (sets, lists, maps) • Strict Concurrency Model (e.g. non-reentrancy)
Overview • What is Whiley? • Hybrid functional / imperative language • Designed specifically for verification • Compiles to JVM (also prototype C backend) • Why another language? • Verification is really hard • Many features of Java it even harder! • I think it’s basically impossible for Java • See ESC/Java and JML as good efforts here
A Zoo of Unusual Types! • Primitives: • e.g. • Collections (lists, sets, maps): • e.g. • Records and Tuples: • e.g. • Unions and Intersections: • e.g. • Negations • e.g. any null bool int real char [int] {string} {int=>string} {int x, int y} (int,int) int|null int&null !int
Flow Typing intsum([int] items): r = 0 for item in items: r = r + item return r • A flow-sensitive approach to type checking • Types declared only for parameters and returns • Variables can have different types! • Conditionals and/or assignments cause retyping
Flow Typing define Circle as {int x, inty, intr} define Rectas {int x, inty, intw, inth} define Shape as Circle | Rect real area(Shape s): if s is Circle: return PI * s.r * s.r else: return s.w * s.h • Type tests automatically retype variables! • (even on the false branch)
Flow Typing & Unions null|int indexOf(string str, char c): … [string] split(string str, char c): idx = indexOf(str,c) if idx isint: below = str[0..idx] above = str[idx..] return[below,above] else: return[str] • Cannot treat null|intlike an int • Must distinguish cases by explicit type testing Can safely treat x as int here
Verification • Function f(): • Accepts an arbitrary integer … • Should return a natural number … • But, this implementation is broken! define nat asint where $ >= 0 nat f(int x): return x A compile time error!
define nat asint where $ >= 0 nat f(int x): if x >= 0: return x else: return 0 • Function f(): • Accepts an arbitrary integer … • Returns a natural number … • This implementation satisfies the spec! OK, because x implicitly a nat
Verification define nat asint where $ >= 0 define pos asint where $ > 0 nat g(pos x): return x • Function g(): • Accepts a positive number … • And returns a natural number … • But, how to know pos subtypes nat ? OK, because pos implies nat
Verification define nat asint where $ >= 0 define pos asint where $ > 0 pos h(nat x): return x + 1 • Function h(): • Accepts a natural number … • And returns a positive number … • But, how to know nat+1 gives pos ? OK, because nat+1 gives pos
Verification define nat asint where $ >= 0 define pos asint where $ > 0 pos h1(nat x): return x + 1 int h2(int x) requires x>=0, ensures $>0: return x + 1 • Function h1() and h2() are identical
Verification define nat as int where $ >= 0 nat sum([nat] list): r = 0 for x in list where r >= 0: r = r + x return r • Function sum(): • Accepts a listof natural numbers … • Then adds them together … • And returns a natural number. Ok, because adding nat to nat gives nat
Compiler Overview • Developed 2009 – present • 304 classes (80KLOC) with 934 end-end tests • Also, 133 verifier tests and 15178 type system unit tests
Eclipse Plugin • Update Site: http://whiley.org/eclipse
http://whiley.org @whileydave http://github.com/DavePearce