From romanowski.mateusz at gmail.com Wed Dec 11 17:53:30 2019 From: romanowski.mateusz at gmail.com (Mateusz Romanowski) Date: Thu, 12 Dec 2019 02:53:30 +0900 Subject: Lifting operations from inline classes to reference projections In-Reply-To: References: Message-ID: Hi Brian et al, Could you please show how following package-private inline class would be translated? inline class Point { public Point(int x, int z) { this.x = x; this.y = y; } public Point sum(Point that) { return new Point(this.x+that.x,this.y+that.y); } private final int x, y; } I am wondering how the client of public reference projection would get an instance of the private implementation inline class. Thanks, Mateusz Romanowski From gneppert at web.de Mon Dec 16 17:08:07 2019 From: gneppert at web.de (Gernot Neppert) Date: Mon, 16 Dec 2019 18:08:07 +0100 Subject: State of Valhalla: array conversions Message-ID: <463cebdf-35d3-f27a-81d3-16419d598829@web.de> Hello, the document states that "For any class X (inline or identity) that implements interface I, the following subtyping relationship holds for arrays of X: X[] <: I[] <: Object[]" While this seems intuitive and consistent with the new "reference-projection", it raises the question: What kind of conversion will the assignment of an array-of-inlines to an array-of-refs be? Of course, a sensible one-way conversion is feasible. But then, the array-of-refs would not be an alias of the original array anymore. Given the following code: int[] a = {42, 43, 4711}; Integer[] r = a; r[1] = -1; I'd expect the assignment r[1] = -1 to modify the original array a, too! It's hard to imagine how that could be efficiently implemented. Regards, Gernot From elias at vasylenko.uk Fri Dec 20 10:07:39 2019 From: elias at vasylenko.uk (Elias Vasylenko) Date: Fri, 20 Dec 2019 10:07:39 +0000 (GMT) Subject: Reference-default style In-Reply-To: <62c6ee44-5659-5718-0542-3ef144b55109@oracle.com> References: <9041A550-BE7D-4D53-9DE5-FF307DD08BD1@oracle.com> <62c6ee44-5659-5718-0542-3ef144b55109@oracle.com> Message-ID: <1942540089.223334.1576836459644@email.ionos.co.uk> I realise this has been said before, but it does seem particularly pertinent to this discussion so I hope it's not a bad time for a gentle reminder. There is an assumption baked into all these approaches that there is only reliably one "good name" for any given class, but arguably that's not the case. It could be convention that the inline version of a type takes the same name but with a lowercase spelling, e.g. the inline version of `Optional` is `optional`. With this convention, pretty much all inlineable types can reliably have a good name to refer to both inline and reference variants. As an added bonus, users can easily distinguish between them at the use site at a glance (assuming adherence to the convention can be relied upon). This naming convention also happens to be convenient for migrating existing classes such as `Optional` and `DateTime`; we just introduce inline versions called `optional` and `dateTime` (or `datetime`?). This also works out neatly for primitives and their wrappers. This doesn't obviate the need for the `.inline` and `.reference` type operators for two reasons. One, it would be icky to mechanically derive the alternate spelling, and we might not always want to force users to write both names down. Two, for type parameters. (For that matter why no `T.erased` operator? But that's not relevant.) So perhaps there are a couple of other options. 6a) A single inline class declaration introduces two types, either one or both of which can be named. If only one name is provided it goes to the inline type. // create an inline class `point` with an unnamed reference projection public inline class point { /*...*/ } // create an inline class `optional` with a reference projection `Optional` public inline class optional reference Optional { /*...*/ } 6b) As above, except if only one name is provided it goes to the reference type. // create an unnamed inline class with a reference projection `Node` public inline class Node { /*...*/ } // create an inline class `optional` with a reference projection `Optional` public inline optional class Optional { /*...*/ } The bikeshedding on how they'd be declared is just for the purposes of illustration and not a serious suggestion. The point is, I think if the barrier for declaring *two* "good names" is low enough then worrying about "inline default" vs "reference default" becomes redundant. > On 20 December 2019 at 00:10 Maurizio Cimadamore wrote: > > > On 19/12/2019 21:15, Dan Smith wrote:> Like many design patterns, (1) suffers from boilerplate overhead ((2) too, without some language help). It also risks some missed opportunities for optimization or language convenience, because the relationship between the inline and reference type is incidental. (I'd like to get a clearer picture of whether this really matters or not.)At the last post JVMLS meeting I was a string advocate of this position.This is effectively the pattern used in the Panama memory access API,where we have public (in future sealed) interfaces backed up byinline-ready implementation classes. > While I still think that there will be a lot of cases like these -Panama also needs something which is more akin to the 'programmableprimitive'-half of the Valhalla glass. That is, we might want tointroduce a int128 type or float16, which might be required to interopwith certain system ABIs. > When you do that, you would like to have these types (e.g. int128) the*public* ones, the ones with the good names. You want users to create(flat) arrays of them, rather than oops arrays. > So, as much as I like (1) I don't think we can fully get away with that? > Maurizio