-
Notifications
You must be signed in to change notification settings - Fork 207
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
Support generic arguments for (named) constructors #1510
Comments
I have encountered this in other parts of the core libraries as well. |
The biggest issue is, that the syntax works much less nicely for unnamed constructors. |
I have a few cases too where I could have used that too. I don't think it's a big problem that it doesn't work for the unnamed constructor. Writing |
I haven't encountered one yet, and I agree that this seems like a reasonable restriction. |
I think it makes a lot of sense to have this feature. It shouldn't be much extra work on top of all the other kinds of generic routines we have already, and it looks like an oversight to omit it. The main use for it would be to ensure consistency among type parameters used in the types of ordinary parameters. It would probably not make much sense for the newly created object to store the actual arguments or anything else which is directly characterized by |
@eernstg @floitschG @lrhn @munificent Is this something we can take on soon? It seems useful. |
One funny little thing is that a constructor may use a generic named constructor in a superinitializer, so we need support for Given that there is no return value from a constructor we generally won't have a contextual expectation available during type inference for these type arguments, but the type arguments would presumably be used to "fill in some coordinated blanks" in the types of value arguments, so type inference is likely to be able to provide the type arguments. So there will be some corners of this feature which are new, but probably no show-stoppers. |
On minimal thought, I would expect that if we have:
then you could use |
The starting point is that we are adding a new construct: It's about the type arguments of a named constructor itself, not the type arguments of the enclosing class. E.g., in class A {
int x;
A.make<T>(String s, int Function(T) f, T Function(String) g) {
x = f(g(s));
}
}
class B extends A {
B.make(String s): super.make<int>(s, (s) => s.length, (i) => i);
} I noted that we don't have a return type since this is a constructor, and the type arguments of the constructor itself would not be able to occur in the type of the newly constructed object, and hence we couldn't use a return type nor the type of In practice, I expect these type arguments to be used to bridge some gaps in the typing of the actual arguments, like in the example. This seems to imply that "transfer of information from one argument to another" will be important for this particular kind of inference. However, my conclusion was that this isn't actually new (the same difficulties can arise in concrete examples today), so we should probably just get started. ;-) |
I'm in favor of getting this done. As Natalie mentioned: we have cases where we need those in the core library, and there shouldn't be any big show-stoppers. |
I would really like this feature too. |
Similar dart-lang/sdk#30041 |
Assuming this doesn't make it into Dart 2.0, it wouldn't be considered a breaking language change, so that it could be added soon after, correct? Like Dart 2.1? I've gotten many questions about this, mostly regarding |
Don't hold me to this:
|
It's not a breaking change to the language. It's just a case of a feature not making it into Dart 2.0, like a lot of other good features. It's pretty high on my list of annoyances to address ASAP. Constructors are basically static methods, and we don't have tear-offs of them yet, so any change to the signature that allows all existing calls should be safe. The example above ... is a breakage I would be willing to allow. Map.fromIterable<T>(Iterable<T> elements, {K key(T element), V value(T
element)}) then any good code should still work. It took an empty list above to get something mis-typed through without causing a runtime error. |
Any updates on this, now that we're post-2.0? |
Can you be explicit and say |
The support of generic arguments for named constructors is also needed in this case:
|
No update. We're currently hard at work on non-nullable types and extension methods, so we probablty won't get to this until those are done. |
Moving to the main language repo |
Note that this issue (when located in the SDK repo) was already mentioned as one of the existing proposals for exactly this feature in #647 (comment). So we may wish to close one of these as a duplicate of the other one, to avoid fragmenting the discussion and the support. |
Good point, let's continue the discussion in #647 |
Sometimes constructors need to have generics that don't appear in the class itself in order to fully express their type relationships.
new Map.fromIterable()
is a good example:If
elements
has a generic type, thekey()
andvalue()
callbacks are guaranteed to be passed an argument of that type, but there's currently no way to express that. Using generic types here blocks inference and makes it very difficult to use this API in strong mode. I propose that we be able to declare:which would be called like
new Map<String, String>.fromIterable<int>(...)
. This syntax allows the user to omit the generic argument to the constructor while retaining it for the class itself if desired.The text was updated successfully, but these errors were encountered: