Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Project Valhalla and Value Types

Project Valhalla and Value Types

A short introduction to the Valhalla project.
Remaining open problems and examples on the current syntax.

Uberto Barbini

January 10, 2019
Tweet

More Decks by Uberto Barbini

Other Decks in Programming

Transcript

  1. Valhalla Project Valhalla Started 2014 JEP 169: Value Objects JEP

    218: Generics over Primitive Types Uberto Barbini @ramtop
  2. pe Value Types “Codes like a Class works like an

    int” Reference Immutability Nullability Primitive Generics
  3. Which Field Descriptor for VT? B byte signed byte C

    char Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16 D double double-precision floating-point value F float single-precision floating-point value I int integer J long long integer L ClassName ; reference an instance of class ClassName S short signed short Z boolean true or false [ reference one array dimension
  4. e Phase I focused mostly on language and libraries, trying

    to wrap our heads around exactly what a clean migration to value types and specialized generics would look like. At which point we realized the list of VM requirements was implausibly long and we needed to come at this from the other direction for a while. Phase II attacked the problem from the VM up, with two more rounds of prototypes -- MVT and LW1. LW1 was a risky experiment; we hoped, but weren't sure we could get away with, sharing the L-carrier and a* bytecodes between references and values, without losing performance. If we could do so, many of the problems we discovered in Phase I could go away. And, all evidence seems to suggest that this was successful, and we have a much richer base to build on. So, I think this demarcates the start of Phase III -- where we have a solid enough proof-of-concept that we can largely graduate from the "risky experiments and wild theories" portion of the program (at least for the VM). Fantastic work from everyone involved to get us here! Brian Goetz 5/10/2018
  5. e Q-Types in L-World 10 For any given named class

    or interface Foo we say that L-Foo is the L-type of Foo. When the type is obviously not a value type we may omit the “L-” prefix, thus Object and Object[] for L-Object and L- Object[]. As dictated by today’s JVMS, any variable of L-type will accept null. A Q-type is a reference to a value instance. All value instances have a named class, which is incorporated into the spelling of the Q-type. (For regularity we say “reference to a value”, but the reference is not detectable to the user; there are no identity or aliasing relations between values.) For any given named value class Val we say that Q-Val is the Q-type of Val. http://cr.openjdk.java.net/~jrose/values/q-types.html September 2018
  6. e # Finding the Spirit of L-world While I think

    we made a lot of progress, I think we fell into a few wishful-thinking traps with regard to the object model that we are exposing to users. L-World is, at heart, an attempt to unify reference objects and values; they're unified under a common top type (`Object`), a common basic type descriptor (`L`), and a common set of bytecodes (`aload` et al.) The war cry for L-World should be, therefore, "Everything is an Object". Brian Goetz – 9 Jan 2019
  7. pe Constructors final value class Point { public final int

    x; public final int y; public Point(int x, int y) { this.x = x; this.y = y; } public static Point of(int x, int y) { Point p = Point.default; Point p1 = __WithField(p.x, x); //WithField operator is allowed only with -XDallowWithFieldOperator Point p2 = __WithField(p1.y, y); return p2; }
  8. Implement Interfaces public value class Dog implements Animal { public

    final String name; public Dog(String name) { this.name = name; } @Override public String name() { return name; } @Override public String sound() { return "woof"; } }
  9. Inheritance public class Alsatian implements Animal { //Ok public class

    Alsatian extends Dog { // Error: cannot inherit from final com.gamasoft.animals.Dog public value class Alsatian extends Dog { // Error: value type may not extend another value or class
  10. toString() public value class Cat implements Animal { public final

    String name; public Cat(String name) { this.name = name; } @Override public String name() { // return super.toString(); //Error: value types do not support invocation of super.toString return name; }
  11. Equals == var p1 = new Point(3, 4); var p2

    = new Point(4, 5); var p3 = p1.displace(1,1); assertEquals(p2, p3); assertTrue(p2 == p3); //Error: value types do not support ==
  12. p Equals() or == ? Currently == doesn’t work on

    Value Types Users will expect (100% reasonably) the following to work: Point p1, p2; p1 == p1 // true p2 = p1 p1 == p2 // true Object o1 = p1, o2 = p2; o1 == o1 // true In LW1, if we map `==` to `ACMP`, they do not, and this will violate both user intuition and the spirit of "everything is an object".
  13. Arrays var memBefore = Runtime.getRuntime().freeMemory(); Point[] values = new Point[1_000_000];

    var memUsed = memBefore - Runtime.getRuntime().freeMemory(); System.out.println("Memory for 1M Points " + memUsed); //8MB System.out.println("Point default " + values[0]); //???
  14. Nullability var list = new ArrayList<Point>(); list.add(Point.of(3, 4)); list.add(null); //Error:

    incompatible types: <nulltype> cannot be converted to com.gamasoft.Point assertEquals(1, list.size()); assertEquals(new Point(3, 4), list.get(0)); assertEquals(null, list.get(1));
  15. Boxing from the language perspective, one can create a value

    type using a "value class" VT or a nullable value type NVT with the annotation @ValueBased. The language let you automatically derive - a nullable value type VT.box from a value type VT and VT.val is equivalent to VT. - a non nullable value type NVT.val from a nullable value type NVT and NVT.box is equivalent to NVT. Remi Forax
  16. Generics var d = new Dog("Lassie"); //VT var c =

    new Cat("Ginger"); //VT var s = new Shark(); //Object List<Animal> animalList = new ArrayList<>(); animalList.add(d); animalList.add(c); animalList.add(s); Set<Cat> catSet = new HashSet<>(); catSet.add(new Cat("Tom")); catSet.add(new Cat("Jerry")); catSet.add(new Cat("Silvester"));
  17. Flattenable public value class Line { public __Flattenable final Point

    startPoint; public __Flattenable final Point endPoint; public Line(Point p1, Point p2) { this.startPoint = p1; this.endPoint = p2; } } var memBefore = Runtime.getRuntime().freeMemory(); var values = new Line[1_000_000]; var memUsed = memBefore - Runtime.getRuntime().freeMemory(); System.out.println("Memory for 1M Lines " + memUsed); //16MB
  18. Ideas for exercises https://github.com/uberto/testValueTypes Generic code with VT Mixing in

    Collections Challenge Immutability Using VT in Objects Using Objects inside VT Performance comparison