disallow or define semantics for "default late" values
See original GitHub issueWe know that for:
class C() {
shared default String x = "C's value";
}
the specification = "C's value"
is for C
’s x
, and not a potential refinement of x
. This can be demonstrated with the following test:
class D() extends C() {
shared actual variable String x = "D's value";
shared void test() {
assert (super.x == "C's value");
}
}
We also know that specifications (assignments) made separately from a declaration are polymorphic in nature:
class C() {
shared default variable String x = "C's value";
shared void update() {
x = "newValue"; // C's x may still be "C's value"!
}
}
This can also be demonstrated with the D
test above.
However, for late
values, initialization may be separated from the declaration, introducing an ambiguity for values that are also default
:
class C() {
shared default late String x;
shared void initialize() {
x = "C's value"; // Are we initializing C's x, or possibly assigning to
// a refinement of x? What if the refinement is or is not
// itself late or variable? What if we also mark C.x
// variable?
print(x); // This would certainly refer to a refinement
}
}
The backends are inconsistent WRT their treatment of default late
members.
I propose that default late
be disallowed. Other options may be possible too (I debated them with myself here: https://github.com/jvasileff/ceylon-dart/issues/11), but I’m not sure they would be worth the complexity and possibly surprising results.
Issue Analytics
- State:
- Created 7 years ago
- Comments:30 (30 by maintainers)
Top GitHub Comments
Alright, so after reviewing the above discussion, I guess @jvasileff has more or less convinced me that it’s worth outlawing
default late
even independently of #4273. So I’ve done that. I’ll close this issue and reopen the ancient issue #4273.And I guess this is exactly why I have not been inclined to solve #4273 in the 3 years it has been open. There’s probably no static-analysis based solution that isn’t unacceptably restrictive.
This is a reasonable solution involving maintaining a
$$isFullyInitialized$$
member for any classes which leak theirthis
reference. But it gets a little hairy to implement in the face of inheritance.