Skip to content
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

Closed
peter-ahe-google opened this issue Jan 2, 2013 · 8 comments
Closed

Is the Dart type system is nominal? #7639

peter-ahe-google opened this issue Jan 2, 2013 · 8 comments
Assignees
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue

Comments

@peter-ahe-google
Copy link
Contributor

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.

@peter-ahe-google
Copy link
Contributor Author

Marked this as blocking #7622.

@gbracha
Copy link
Contributor

gbracha commented Jan 2, 2013

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.

@peter-ahe-google
Copy link
Contributor Author

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.

@gbracha
Copy link
Contributor

gbracha commented Jan 4, 2013

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.

@peter-ahe-google
Copy link
Contributor Author

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.

@lrhn
Copy link
Member

lrhn commented Jan 17, 2013

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.
The only use for the Function type is as a statement of intent: You declare your variable to have type Function instead of var/Object in order to document that it expects a callable object. We even use that in assert statements: if the result of evaluating the expression is a subtype of Function, then we call it with zero arguments - even if it's not a nullary function. That must work with user-declared callable objects too.
The alternative is that Function is unusable for even that, and then it should be removed.

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?

@gbracha
Copy link
Contributor

gbracha commented Jan 17, 2013

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.

@gbracha
Copy link
Contributor

gbracha commented Jan 2, 2015

This won't change at this stage.


Added WontFix label.

@peter-ahe-google peter-ahe-google added Type-Defect area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Jan 2, 2015
@kevmoo kevmoo added closed-not-planned Closed as we don't intend to take action on the reported issue and removed resolution-wont_fix labels Mar 1, 2016
This issue was closed.
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-not-planned Closed as we don't intend to take action on the reported issue
Projects
None yet
Development

No branches or pull requests

4 participants