Skip to content

Should tuples be equivalent to argument lists? #1293

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

Open
lrhn opened this issue Nov 7, 2020 · 4 comments
Open

Should tuples be equivalent to argument lists? #1293

lrhn opened this issue Nov 7, 2020 · 4 comments
Labels
patterns Issues related to pattern matching. question Further information is requested

Comments

@lrhn
Copy link
Member

lrhn commented Nov 7, 2020

The current proposal for tuples allow named entries and positional entries, and can in many ways be seen as an abstraction over argument lists. It's not complete, because it doesn't cover the empty tuple, but it does have a singleton tuple.

If we allow tuples to work like argument lists, then every function can now be seen as an unary function from a tuple type to its result. (We might not allow f tupleVariable to call the function, but that's mainly for syntactic reasons, not because it doesn't make sense, and we can probably allow f(...tupleVariable)).

If argument lists are tuples, then tuple types should be parameter lists. The syntax is already close, a tuple type can be used as the parameter types of a Function type, e.g., (int, int, {int x}) can be used as void Function(int, int, {int x}).
It's not a complete match though:

  • No zero element tuple type.
  • Tuple types cannot have optional positional entries.
  • Tuple types cannot have optional named entries either, so the type above should really be void Function(int, int, {required int x}).
  • Some names are not allowed for named entries because the conflict with Object members.

Still, if we ignore optional parameters for now, we can see tuple types as the shape of a parameter list.
We could then allow spreading a tuple type into a parameter list:

typedef F<R, P extends Record> = R Function(... P);

That could allow some abstraction over the "width" of a tuple.
It would probably be too complicated, but it could (highly speculatively) allow for something like

R invoke<R, P extends Record>(T Function(... P) f, P args) => f(...args);

That's probably too ambitious (would make more sense for a language where functions were always unary and tuples were built in from the start, like ML).

@lrhn lrhn added question Further information is requested patterns Issues related to pattern matching. labels Nov 7, 2020
@lrhn
Copy link
Member Author

lrhn commented Nov 7, 2020

If we go for "everything like in function definition", probably more like everything in a function type definition, then we have optional parameters (both optional positional and optional named, but not at the same time).

I'm not sure it's the right design for tuple types.
If you do (int, int, [int]) p = tuple;, I'd expect you to only be able to use the first two entries, but for functions, you get the third entry as well, with a default value. Or alternatively, the assignment is not valid because the third entry needs a default value, so it'd be (int, int, [int = 0]) p = tuple;.

It's not a slam-dunk, but I guess it can work.

@munificent
Copy link
Member

That's probably too ambitious (would make more sense for a language where functions were always unary and tuples were built in from the start, like ML).

Yeah, I think we will eventually hit a wall if we try to push too far in this direction. Dart isn't ML and Dart-y tuples will probably not be 100% like ML tuples.

I look at records in Dart more pragmatically: it's an immutable collection that the type system can see into. Nothing more, nothing less. Spreading a record into an argument list is a natural extension of that, but I don't think we need to reach 100% parity between tuple types and parameter lists for that to work.

@lrhn
Copy link
Member Author

lrhn commented Nov 19, 2020

If we don't need argument-list parity, then I think we can easily go in two extreme directions:

  • Positional entries only. A tuple is a completely semantic-less collection of values. It's physical representation only. Names are semantics, so we don't need them. If you need names, use a class.
  • Named entries only. A tuple is a trivial structural data-only "class". You define the storage fields with names, but not other members.

I think either approach can work.

The "named only" approach might feel overkill if something is really just an unstructured pair, but ... it never is. If a pair occurs as an inherent part of a class or method API (not just a type argument), then each position has a meaning. A MapEntry is not just a pair, it's a key/value pair. A point is not just a pair, it's x/y coordinates. There is always an underlying meaning, and therefore a name, it's just that the name sometimes so obvious that we want to be able to not have to write it. That isn't necessarily a good choice, though (favor explicit over implicit!).

The "positional only" approach is a move towards a physical representation of the data. Semantics must be supplied from the outside. If you want to assign names to the parts, it's your job, not part of the tuple. (Maybe we can have "static names", so a tuple can be defined as (int x, int y) point = ...; print(point.x + point.y);, where the x is part of the point declaration, not the underlying run-time tuple, which is just (int, int).)

Mixing the two muddies the waters. Which one is "the right one" depends on which problem tuples/records are intended to solve.

@mateusfccp
Copy link
Contributor

mateusfccp commented Nov 19, 2020

As I am biased to ML I would love to see a complete equivalence. I know that there are some limitations to it in the context of Dart, tho.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
patterns Issues related to pattern matching. question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants