-
Notifications
You must be signed in to change notification settings - Fork 214
Support generic function instantiation for callable objects? #1827
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
Comments
I think we've asked for that behavior explicitly. As I remember it, we effectively specified implicit (The latter is referred to as "implicit property extraction" in the spec, but only mentioned in relation to extension methods where it doesn't apply.) Also, we allow instantiated instance method tear-off if an instance method tear-off for a generic instance method occurs with a context type which is a non-generic function type, and we can find a matching instantiation. (That's just the definition of instantiated instance method tear-off, just like other instantiated tear-offs we allowed.) Together those two should just make the instantiated callable object We then explicitly added rules to disallow that combination in order to avoid callable objects from being more useful than normal function closures. (I may be misremembering this, and we never did any exception, and I'm just remembering the "don't do implicit If we allow general generic function value instantiation (#1812), not just tear-off instantiation, then there is no reason for such a restriction any more (whether we had it or not). class A {
X call<X>(X x) => x;
}
void main() {
X Function<X>(X) f = A(); // This should *always* have worked. It's just an implicit `.call` tear-off
Function g = A(); // This too should just work, and do a tear-off of the generic `call` method.
int Function(int) h = A(); // This used to be disallowed, but should be made to work.
var j = A()<int>; // This too will be valid, we now insert `.call` if followed by type arguments or arguments.
} (The constructor tear-off specification already includes this, I never thought it wouldn't work.) |
Closing: This is already working, and the spec is updated accordingly in #1842. |
Uh oh!
There was an error while loading. Please reload this page.
The language specification allows for something that we could informally describe as invocation of callable objects:
We have specified that expressions of the form
a(...)
ora<T1..Tk>(...)
are desugared toa.call(...)
respectivelya.call<T1..Tk>(...)
when the static type ofa
is a class that has a method namedcall
(not a getter). The desugared forms may have compile-time errors, but then we just report them.In general, we can take the cue directly from the expression syntax: We are using
e(...)
ore<...>(...)
, hence the expressione
must denote a function.We do not have a similar rule for function closurization, and we do not have a similar rule for generic function instantiation:
However, the current implementations (
dartanalyzer
,dart
,dart2js
at least) do allow the function closurization (apparently based on the context type), but they reject the generic function instantiation.I think the consistent approach at this point would be to allow both the closurization (because it would be a breaking change to disallow it) and the generic function instantiation (because of the generalization in #1812).
We could consider this approach to be reasonably consistent, because it allows "all usages" of callable objects as functions, as long as the static type allows the compiler to use a small desugaring step to achieve the semantics that corresponds to the semantics that we would have with an actual function object.
If we do this we'd need to update the language specification as well as the constructor-tearoffs specification.
@munificent, @jakemac53, @lrhn, @stereotype441, @leafpetersen, @natebosch, WDYT?
The text was updated successfully, but these errors were encountered: