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
Is the Dart type system is nominal? #7639
Comments
Marked this as blocking #7622. |
Function types are usually handled structurally, as are generic invocations. So one rarely gets a pure nominal system in practice. But that is beside the point. The real question here is whether user defined classes that seek to emulate functions must do something more than just define call(). The downside has been noted in the bug: we have types that implement Function without saying so. The upside is that users do not have to explicitly declare that they implement Function, and so they cannot forget to do so. Hence we do not need to worry about such inconsistencies. We discussed this possible inconsistency at length and came up with a spec that eliminates it. Note that this is independent of the question of whether to replace call() with a special operator (). The same question would arise. Added AsDesigned label. |
I would argue that it should be a warning if a class implements Function without declaring it explicitly. That way, the type system stays nominal as far as declared classes go. Function types would remain the one exception as they are structural. Added Triaged label. |
I'll bring it up for discussion. I disagree, and view this as extra hassle for the user. Perhaps we should go to operator () after all, that way I think whatever argument there is here will hopefully disappear. Added Accepted label. |
In my opinion, this issue is orthogonal to the method name ("call" or "()"). As a matter of principle, I think it is important that you state intent explicitly and don't rely on subtle rules that are hard to discover. Having an explicit declaration means that tools don't need special logic to visualize this additional interface (I'm thinking of dartdoc and the Editor in particular), and it makes it easier for the user of a class to see what types a class implements without the aid of additional tools. |
If a callable object doesn't automatically implement Function, I'd prefer just dropping the Function type entirely. It has no members except for what it inherits from Object, and it shouldn't ever get any - a user declared callable object should be as good as a "Real" function without doing anything except implementing the call operator/method. As for a nominal type system, we have function types that do not correspond to a class. The Function type is a supertype of all these, but is a class type (per the spec). Would it be easier to just make it not a class type? |
I agree that Function is useful as an indication of intent. It won't do to make it more special than it is - it is a class and it serves as a sensible home for apply(). I don't think anything needs to change. |
This won't change at this stage. Added WontFix label. |
As of version "Draft Version 0.20, M2 release, December 13, 2012", the specification says:
"A function is always an instance of some class that implements the class Function. All function types are subtypes of Function. If a type I includes a method named call, and the type of call is the function type F, then I is considered to be a subtype of F."
This leads to the surprising feature that some classes may implement the Function interface without declaring that they do.
The text was updated successfully, but these errors were encountered: