Skip to content

Typedefs and generic function types - some clarification and/or updates needed #10

@chalin

Description

@chalin

Executive summary

Dart currently has support for generic function type (GFT) aliases via typedefs. Hence some statements in the proposal might not be quite accurate: e.g.,

  • Lack of syntax for GFTs (though there is lack of syntax for generic functions).
  • GFT's cannot be used to instantiate type parameters.

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):

Generic function types are second class in the type system, and do not need to be reified at runtime. Consequently: there is no syntax for a generic function type; type parameters may not be instantiated with generic function types; functions and methods may not be abstracted over generic functions.

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:

functionTypeAlias:
    functionPrefix  typeParameters? formalParameterList ;
functionPrefix:
    returnType? identifier

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

typedef int Compare<T>(T a, T b);

class SortedCollection<T> {
  Compare<T> compare;
  SortedCollection(this.compare);
}

Reification. GFT aliases are indeed not reified:

int sort(int a, int b) => a - b;
SortedCollection c = new SortedCollection<int>(sort);

void main() {
  print(sort.runtimeType);      // -> (int, int) => int
  print(c.compare.runtimeType); // -> (int, int) => int
}

Arguments to type parameters. GFT aliases can be used as arguments to type parameters:

typedef int CompareInt(int a, int b);

class SortedCollection2<T, U extends Compare<T>> {
  U compare;
  SortedCollection2(this.compare);
}

void more() {
  SortedCollection2 c2 = new SortedCollection2<int,CompareInt>(sort);
  //...
  int sortString(String a, String b) => a.length - b.length;
  SortedCollection2 c2s = new SortedCollection2<String,Compare<String>>(sortString);
  //...
}

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).

typedef S T2S<S,T>(T x);
typedef Option<S> OptionMap<S,T>(T2S<S,T> f);

abstract class Option<T> {
  Option<S> map<S>(T2S<S,T> f);  // Ok
  OptionMap<S,T> map<S>;         // Illegal, ... or maybe not?
  T get val;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions