Skip to content

Whether the variable name in the tuple should be forbidden? #3044

Not planned
@Silentdoer

Description

@Silentdoer

Whether the variable name in the tuple should be forbidden because it cannot be used, e.g. (double x, int a) should only be written as (double, int)?

(double, int $2) Is this writing also prohibited?

Activity

added
requestRequests to resolve a particular developer problem
on May 5, 2023
lrhn

lrhn commented on May 5, 2023

@lrhn
Member

Why should we disallow names for positional fields in record types?

Is it confusing that it's allowed? Is it too easy to forget the {...} around the named fields?

We deliberately allow names for positional record fields in record types, the same way we allow names for positional parameters in function types, even if they have no functional effect. They can be used for documentation.

So, it's fine to write:

Iterable<(K key, V value)> mapEntries<K, V>(Map<K, V> map) => map.entries.map((e) => (e.key, e.value));

The names are useful here.

We currently disallow names that would conflict with another field's name.
We don't allow (int foo, {int foo}) or (int, {int $1}) because those names would conflict with other names,
or even (int, int $1).
We do allow (int $1, int $2) because those name won't conflict with the name of another field.

So, all in all, the current behavior is consistent and by design.

If you don't want to write names for positional record fields, you can obviously choose to not do so.

munificent

munificent commented on May 5, 2023

@munificent
Member

Agreed with @lrhn. While names on positional fields in record types are somewhat confusing, it's also useful for documentation and consistent with positional parameters in function types. This was a deliberate design choice.

Silentdoer

Silentdoer commented on May 5, 2023

@Silentdoer
Author
Reprevise

Reprevise commented on Nov 13, 2023

@Reprevise

We can use the name of the function parameter, but the position parameter name of the tuple can only be replaced with a symbol such as $1. The return value type is (int a, int b), res.a is not allowed, it can only be res.$1

I'm sure there's a reason for not allowing it, but I would like to be able to access my positional parameters by name. My project has some "refactors" of removing classes like _ChartData and replacing them with record typedefs, and we need to make the choice between making the record named, and updating the "constructors", or making them positional like the class, but updating the accessors to $1 or $2 when we should just be able to access it by name regardless. I'm sure there's an elaborate discussion in a separate issue on this subject but I can't find it right now.

typedef _ChartData = (DateTime date, double value);

final _ChartData data = (/* */);
print(data.date) // should work imo

final class _ChartData {
  const _ChartData(this.date, this.value);

  final DateTime date;
  final double value;
}

final _ChartData data = _ChartData(/* */);
print(data.date); // works fine
munificent

munificent commented on Mar 11, 2024

@munificent
Member

I'm sure there's a reason for not allowing it, but I would like to be able to access my positional parameters by name.

Issue #3487 goes into this in some detail.

My project has some "refactors" of removing classes like _ChartData and replacing them with record typedefs

If it were me, I would consider keeping those classes. If you have a type that has a meaningful name, meaningful state, accessors for that state, and you want to write a constructor for it... that's a class.

Reprevise

Reprevise commented on Mar 11, 2024

@Reprevise

If it were me, I would consider keeping those classes. If you have a type that has a meaningful name, meaningful state, accessors for that state, and you want to write a constructor for it... that's a class.

The contents of the class _ChartData are listed in full above, it wasn't shortened for readibility. Considering that, I went with using named records and nothing else had to be changed, and now we have the benefit of implicit equality. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    requestRequests to resolve a particular developer problem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @munificent@lrhn@Reprevise@Silentdoer

        Issue actions

          Whether the variable name in the tuple should be forbidden? · Issue #3044 · dart-lang/language