-
Notifications
You must be signed in to change notification settings - Fork 213
Variadic Generics #2532
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
Duplicate of #1774. |
Interesting. It seems it allows abstracting over type transformation, which would be something like first class type aliases, and over the shape of a type collection. Consider something like: F<...T> recordMap<T extends Record, typedef F<X>>(T value, F<X> action<X>(X value)) {
value.map(action); // Preserve shape, apply action to each value.
} which takes a record type and value, and a unary type alias (takes one type and yields a type), I really, really do not know how I'd type that in a statically typed language. It makes sense for Python, which is dynamically typed and generally allows introspection. Also, abstracting over record shape (first class shapes!) is not on the table. |
Not quite sure what the typedef does here, however I might have typed it like this: T<...F<Ts>> recordMap<T extends Record, typedef F<X>, ...Ts>(T<...Ts> value, F<X> action<X>(X value)) {
value.map(action); // Preserve shape, apply action to each value.
} And yes if this action can take any type and transform it to any type it would be difficult to type, but if it just follow normal Generics rules, then functions like: these seems possible. List<X> action<X>(X value) => [value, value, value];
int action<X>(X value) => 0;
X action<X>(List<X> value) => value.first; // here in recordMap is should be a tuple of lists for this to work. But still it is a complicated language feature, and it seems that also Rust have tried this, but it does not look like they managed it: rust-lang/rfcs#376 But I just wanted to share my thoughts in case some from the Dart team had any good ideas ;) |
Case
When we get Records, a table implementation could look like this:
and be used like this:
This gives nice typing since we know that the compiler will make sure that our types of each cell in a row and each column match. For more info on this example see #2531.
Problem
There is a need for several InfoTableN implementations, which is a lot of repetitive code, and of course the user have to specify InfoTableN instead of just InfoTable.
Other possible solution
Metaprogramming
Metaprogramming might allow us to just write how each InfoTableN should be implemented and it would then generate a given number of implementations.
We would still have to specify the N in InfoTableN when using the table (just a minor inconvenience) but the metaprogramming might be a lot more difficult to implement or it might not support this use case. And there would still have to be generated all implementations of InfoTableN instead of just 1.
Main idea
Variadic Generics
We could specify using a class InfoTable (using normal dart + Variadic Generics) and having the number of argument in the Records be variable.
Here we would not have to generate multiple classes so we could create the table just by using InfoTable (no need to specify the N), and would not need metaprogramming which might be more complicated than the usual Dart.
In Python
Variadic Generics will be added to python 3.11 and the specs are in this PEP: https://peps.python.org/pep-0646/
Here is an example, (*iterable in python is similar to the ...iterable in Dart):
Example syntax in Dart:
The idea behind the syntax is to use the same operator as in Python * however in dart the syntax is ... so we use that, and it must be used when specifying the generics as the example above: InfoTable<...Cs, D> (as in Python).
And then every time we use Cs (the name of our varadics) then it is understood as just one of the variable number of elements. and then we can put in in other types like InfoColumn and it must have a ... somewhere in front and only then will it fold out the types in a Record or other type that support a variable number of inputs (InfoTable could be used in some other code where some variadic generic ...As could be used for InfoTable<...As, D>)
Other example
The text was updated successfully, but these errors were encountered: