Description
issue #29777 revealed yet another scenario where the lowest-upper-bound unification can work against users intent.
I have talked to @leafpetersen a number of times about better strategies, and the answer seems to be that no single strategy is perfect.
What about a new keyword such as exact
, that lets the individual API opt into the constraint unification strategy?
bool regularEquals<T>(T a, T b);
bool strictEquals<exact T>(T a, T b);
...
regularEquals("foo", 123); // no type error, unified as regularEquals<Object>()
strictEquals("foo", 123); // type error
strictEquals("foo", "bar"); // correct, unified as strictEquals<String>();
strictEquals<Object>("foo", 123); // correct: "foo" and 123 are both Objects. No unification necessary
I think only one new strategy would be needed (exact). But I could also imagine greatest-lower-bound checks to be useful:
void runBoth<greatest T>(void firstJob(T input), T secondJob(T input), T val);
final merged = runBoth((int n) => ..., (num n) => ..., 1); // no type error, infer T as int
// as opposed to
void runBothExact<exact T>(void firstJob(T input), T secondJob(T input), T val);
final merged = runBothExact((int n) => ..., (num n) => ..., 1); // type error, T is both int and num.
arguably the regular inference rules should be usable with a user-specified upper bound.
bool nonObjectEquals<T upto Object>(T a, T b);
nonObjectEquals(1, 1.0); // works, lowest upper bound of "num" chosen
nonObjectEquals(1, true); // fails, lowest upper bound of "object" violates "upto Object"
nonObjectEquals<Object>(1, true); // should work? Otherwise this is just `T super Object`.
More likely, I think, there should be one strategy, with a name as simple as exact
, but with the semantics of greatest
. upto X
specifically to me seems presumptuous, though most scenarios that confuse people involving unification are where the inferred type is Object, so maybe a single strategy should be specifyable which has the behavior of upto Object
.
Perhaps a better keyword is foo<strict T>
so that its meaning can be more flexible.