Design decisions: forward reference, corralling, method keys
Brian Goetz
brian.goetz at oracle.com
Mon May 18 18:34:00 UTC 2015
>> But using this new status (ActiveFailed) widens the envelope and
>> introduces some new issues, two are known so far:
>>
>> (A) Thanks, Andrei, for pointing this out. If a variable with
>> initializer is in ActiveFailed an update can move it to Active.
>> What is the value of the variable? Should the initializer be
>> run? If the initializer was the location of the unresolved, it
>> seems silly not to run it. Yet, this would be running arbitrary
>> code on update which is sure to have surprising behavior in some
>> cases. Here are the not so perfect options as I see them:
I think deferring the initializer until later creates more problems than
it solves.
For the case of
C c;
where C is currently undefined, I think our current strategy of
corralling the variable declaration until C becomes defined is fine.
It's only when we try to cross the bridge to
C c = e;
where things get ugly, because this would involve triggering execution
(not merely recompilation) when C is updated. I think that's a bridge
too far.
So, my inclination here is to just reject a variable-with-initializer if
we cannot resolve all the types involved. This may ultimately make it
impossible to cut-and-paste from some constructions, for example:
int x = getFoo();
int getFoo() { if (x == 0) return 1; else return 2; }
but this can still be manually restructured into
int x;
int getFoo() { if (x == 0) return 1; else return 2; }
x = getFoo();
>> (B) The key for classes and variables is determined by just their
>> name. But because of overloading, for methods, the key is the
>> name plus the parameter types. This is fine if the method
>> signature can be compiled (the body can be stubbed-out as is the
>> case when corralled), as the full qualified name of the parameter
>> types is then known. But if one of the parameter types is
>> unresolved its full name is not known either so the correct key
>> cannot be determined. This is significant because if it is put
>> in ActiveFailed it can updated into Active (or ActiveCorralled)
>> at which point its actual key is then known and a central
>> invariant is that the key for an input does not change, And here
>> is another set of non-ideal options that I can think for this:
This is not an issue of "what should the REPL do"; it is more an
accident of the internal Key abstraction we've created.
I think you left off an option from your list; what about using the text
typed by the user? So
m(foo.bar.Baz)
and
m(Baz)
would have different keys but would point to the same overload of m.
This could cause some UI anomalies but would it present any semantic
challenges?
More information about the kulla-dev
mailing list