-
Notifications
You must be signed in to change notification settings - Fork 4
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
Typedefs and generic function types - some clarification and/or updates needed #10
Comments
I avoided going into this in the proposal, but perhaps I should add some discussion. Here's where my thinking was when I was working through this. First, some background (sorry if this is obvious, but just to get our terminology on the same page). Typedefs in Dart are not actually generic function types (universal types) even though they look a lot like them. What they are is type functions (or type constructors). That is, they are functions from Type to Type, not types themselves. The difference is small, but crucial. The point is that a universal type is a type (or a type schema or... something depending on what type system you live in), whereas a type constructor (Dart typedef) is a thing which can be given some arguments and will produce for you a type as a result. In the case of Dart, they are limited to producing function types, which is one of thing things that makes them so tantalizingly close to being universal function types. So to be precise, the original two statements that this issue is questioning:
are in fact accurate: you cannot in Dart write the type of a generic function (only a generic which produces a function type); and you cannot instantiate a type parameter with a generic function type (you can only instantiate the typedef and use the result to instantiate a type parameter). I don't make this distinction to be pedantic - there are two different notions there, and the difference is really important. It is also true though, that type constructors provide all of the basic functionality needed to build universal types. So if we ignore backwards compatibility, it would work perfectly well to take the interpretation that:
So then we would have that This is all grand, except for that pesky "ignore backwards compatibility part". Unfortunately, Assuming that we didn't want to bite the bullet on the breaking change, this could be worked around fairly easily. One approach would be to simply have different syntax for introducing a type function versus a generic function type:
Another approach would be to have syntax for lifting an existing typedef up to a universal type: e.g.
The lifting could be done by picking a new keyword as above (minor breaking change), or by using some new syntax or tokens ( In any case, since I decided to push this proposal in the direction of second-class generics, the entire question of syntax for generic function types is fairly moot for the time being. If the committee feels that a more powerful form polymorphism is desired I can revisit this. To address your last question about interactions between existing Dart typedefs and generic functions... I don't currently believe that there are any such interactions. To your concrete example:
Hopefully that addresses the bulk of this issue? Based on this and any follow up discussion I'll try to distill out something to add to the proposal text to clarify this as needed. |
Firstly I would like to emphasize that the core of the proposal seems fine. As you have suggested, one of the points raised by this issue has to do with terminology. There is an object language vs. meta language clash with respect to the term "generic function type". Let's look at common usage (object language terminology) first. In Chapter 2 of Dart Up and Running
Also, the first hit when Googling "dart function type" is this article by Gilad which states that:
Now I'll write -type- to mean a Dart (i.e., object language) type, and ^type^ to mean a meta / type-theoretic type (think of the ^ as pointing up for the more abstract concept). Since typedefs can be generic, they support the definition of generic function -types- (-GFTs-). You were correct earlier in stating that a -GFT- corresponds to a type constructor / operator in our meta theory. Reserving the unqualified term "generic function type" to mean ^GFT^ in the proposal is quite fine, as long as typedefs are always referred to as function type aliases in the proposal. I'll submit a PR with a small section for settling terminology; let me know what you think. |
Agreed that the terminology is unclear - put another way, the phrase "generic function type" can be parsed as "generic (function type)" (that is, functions types which are generic, the sense in which dart has GFTs), or as "(generic function) type" (that is, the type of generic functions, the sense in which dart does not have GFTs). Thanks for the PR - I may just take a more global pass to sort out the terminology though, rather than making the reader keep a terminology look aside table in their head. Any suggestions as to a better term for "(generic function) type" that won't cause confusion? Universal function type or polymorphic function type are two obvious candidates. |
Universal function type was the first that came to mind. Since nowhere in the current proposal is GFT taken to mean a typedef, I figured it was simplest at this point just to add a note about terminology. |
Executive summary
Dart currently has support for generic function type (GFT) aliases via
typedef
s. Hence some statements in the proposal might not be quite accurate: e.g.,If these statements are still considered accurate then at a minimum, the proposal should make clear that the unqualified use of the term "generic function type" (GFT) excludes GFT aliases, i.e., those syntactic entities inside typesdefs that look like GFTs.
Details
Here is an excerpt from the "Proposal" subsection (emphasis mine):
Syntax. In a sense, there is syntax for generic function types (though not for generic functions). It is defined as part of the Dart grammar non-terminal
functionTypeAlias
:If you drop the terminating semicolon then the resulting production defines GFTs.
Example. Here is an example of the syntax adapted from a A Tour of the Dart Language section on typedefs
Reification. GFT aliases are indeed not reified:
Arguments to type parameters. GFT aliases can be used as arguments to type parameters:
Typedefs. I think that some mention should be made in the proposal concerning typedefs and their current use in defining GFT aliases. I assume that there will be no unexpected "feature interactions" between this proposal and typesdefs (a statement to this effect could be made explicitly).
The text was updated successfully, but these errors were encountered: