On 15/04/2019 15:38, Brian Goetz wrote:
Let's model the value vs. reference constraint explicitly - e.g. with
'val' and 'ref' type kinds (and let's not open the can worm as to
what the syntax should be, whether it should be a type anno, etc.)
So:
val Object ---> accepts all values
ref Object ---> accepts all references
any Object ---> accepts all references
We explored this sort of thing in Q world. One place where this
really was painful was what it did to generic tvar constraints; we had
an entire new algebra of constraints:
<ref T extends Bound> void m(T t) { … }
which was ad hoc and composed terribly. This hell is _exactly_ the
thing that pushed us to Ref/ValObject as _types_ in the first place.
(More of the same: what is “ref Object”.class, and how does it differ
from “any Object”.class?).
This is not a language proposal (as stated in the email). Just a way to
be clearer about semantics, w/o appealing to subclasses and type
hierarchies (which are, at this point, IMHO confusing).
2) reinterpret `Object` as `any Object`
That is, the semantics of `Object` is being redefined here - code
which assumed to work with references might need to opt-in to
additional constraints (e.g. add `ref`) in order to make sure it
still work as intended.
Right. Q-world tried it the other way, and we were in utter migration
hell. There are migration cases in this direction too, but we are
convinced they are orders of magnitude fewer.
I don't see another way out of this conundrum - other than adding a
special rule (z2) which says that `new Object()` is treated specially
and always has kind `ref`. But doing so will run afoul in almost
every possible way - as soon as you manipulate the result of the
`new` in any way (cast, assignment to variable of type `Object`, ...)
you go back to `any` and you are back to a place that is incompatible
with `ref Object`.
Yes, this is the cost. I have to think that given a choice between
some weirdness around ’new Object’, and dramatic, awful new kinds of
types that complicate type uses, type descriptors, reflection, etc,
etc, etc, that making the former work is going to be less painful,
both for us and for users.
Well, not quite. The choice is between treating 'new Object' specially
or not. If it's not treated specially there is no new scary type. It's
just that`new Object` might not have the properties one might hope for
(but again, those same properties would be lost as soon as you touch the
result of the expression).
I think you took my type modifiers too literally (as if, I'm proposing
to add them, which I'm not) :-)
Maurizio
Your idea of treating Object as abstract is, I believe, a sound one
(which doesn't need any extra rule) - but we might have to figure out
some story for anonymous inner classes of the kind `new Object() {
... }`.
Right. And, again, this can be treated as a migration issue, and we
can start warning users to migrate their source now.