This is more of a question than a suggestion, regarding SIP-15, value classes. First of all, thanks to everyone involved - even with its current limitations, SIP-15 is a great addition to the language.
My question is whether multi-argument constructors for value classes is a planned feature for a future incarnation of this SIP? This can be worked around somewhat by storing, for instance, two floats in a double value, etc... but it is cumbersome for uses cases that need it (vectors for physics simulations, etc...).
The JVM may not have native support for it (yet), but my naive thoughts are that it could be simulated even without native support, with some major limitations, and yet still be incredibly useful:
class Vector2d(val x: Double, val y: Double) extends AnyVal {...}
val i = new Vector2d(1.0, 0.0);
// equivalent to:
// val _i_x = 1.0; val _i_y = 0.0;
// This would always have to be inlined to avoid boxing, or else return a boxed instance of the class
def add(left: Vector2d, right: Vector2d) : Vector2d = new Vector2d(left.x + right.x, left.y + right.y)
val j = new Vector2d(0.0, 1.0);
val k = add(i, j);
// although the add function instantiates boxed values for arguments and the return value,
// the compiler can inline this call into:
// val _j_x = 0.0; val _j_y = 1.0;
// val _k_x = _i_x + _j_x; val _k_y = _i_y + _j_y;
def lengthSquared(v: Vector2d) : Double = v.x * v.y
// could be equivalent performance-wise to:
// def lengthSquared(_v_x: Double, _v_y: Double) = _v_x * _v_y
Collections would of course be tricky, but you could use the traditional solution: multiple arrays of primitives to simulate an array of value types with multiple primitive fields:
var l = new Array[Vector2d](3)
// could be equivalent to:
// var _l_x = new Array[Double](3); var _l_y = new Array[Double](3);
Passing arrays, also similar:
def someVectorArrayAccumulator(vl: Array[Vector2d]) = ...
// could be equivalent to:
// def someVectorArrayAccumulator(_vl_x: Array[Double], _vl_y: Array[Double]) = ...
However, aside from arrays, I think any other generic container (especially if it has more than one type argument) would end up requiring boxing for multi-field value classes, which is unfortunate:
new Tuple2(new Vector2d(1.0, 0.0), new Vector2d(1.0, 0.0)); // should either not be possible or else automatically result in boxing Vector2ds, at least until/unless the JVM supports value tuples natively