Skip to content

Feature request: Specify unification strategy for generic method types #29780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MichaelRFairhurst opened this issue Jun 1, 2017 · 0 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-stale Closed as the issue or PR is assumed stale type-enhancement A request for a change that isn't a bug

Comments

@MichaelRFairhurst
Copy link
Contributor

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.

@MichaelRFairhurst MichaelRFairhurst added analyzer-strong-mode type-enhancement A request for a change that isn't a bug labels Jun 1, 2017
@leafpetersen leafpetersen added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). and removed analyzer-strong-mode labels Jun 2, 2017
@lrhn lrhn closed this as not planned Won't fix, can't repro, duplicate, stale Apr 9, 2025
@lrhn lrhn added the closed-stale Closed as the issue or PR is assumed stale label Apr 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-stale Closed as the issue or PR is assumed stale type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

3 participants