Skip to content
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

Named arguments #4185

Open
cedvdb opened this issue Nov 29, 2024 · 1 comment
Open

Named arguments #4185

cedvdb opened this issue Nov 29, 2024 · 1 comment
Labels
feature Proposed language feature that solves one or more problems

Comments

@cedvdb
Copy link

cedvdb commented Nov 29, 2024

Named argument

As opposed to named parameters, named arguments is about using the parameter name on the call site.

Named arguments enable you to specify an argument for a positional parameter by matching the argument with its name rather than with its position in the parameter list.

Example:

void main() {
  final a = A(x: 1, y: 2);
  final another = A(y: 2, x:1);
}

class A {
  final int x;
  final int y;
  A(this.x, this.y);
}

Rationale:

The decision to use named or positional arguments can be a decision the call site should make.

Private properties

void main() {
  final a = A(x: 1, y: 2);
}

class A {
  final int _x;
  final int _y;
  A(this._x, this._y);
}

Related:

Named argument shorthand

prefixing an argument variable with : uses the same name as the variable name

Example:

void main() {
  final x = 1;
  final y = 2;
  final a = A(:y, :x);
}

class A {
  final int x;
  final int y;
  A(this.x, this.y);
}

Related: Object spread shorthand

Syntax sugar ...Object is used in a constructor / function call to unpack labels:

void main() {
  final a = A(x: 1, y: 2);
  final b = B(...a, z: 3);
  // equivalent to
  final bWithoutSugar = B(x: a.x, y: a.y, z: 3);
}

class A {
  final int x;
  final int y;
  A(this.x, this.y);
}

class B {
  final int x;
  final int y;
  final int z;
  A(this.x, this.y, this.z);

...Object unpack the labels with the intersection between the parameters name and the object getters name.

Copies with null values

The last declaration of the field wins, allowing copying with null values (when the fields are not private).

void main() {
  final a = A(x: 1, y: 2);
  final another = A(...a, y: null);
}

class A {
  final int x;
  final int? y;
  A(this.x, this.y);
}
@cedvdb cedvdb added the feature Proposed language feature that solves one or more problems label Nov 29, 2024
@lrhn
Copy link
Member

lrhn commented Nov 29, 2024

I'm sure I have proposed something like this before, possibly as part of some other feature (I can't find an issue right now).

It's a nice idea which allows users to refer to parameters by name, when they have a name, even if they are not named parameters.

The risks are that the names are not really part of the function value, they're just metadata on the static function types.

  • You can't use those names in a dynamic invocation.
  • Any operation on types may affect the metadata. We'll have to specify precisely how it's propagated through all type operations (with Up and Down being the biggest risks, and Norm probably not mattering since it's only used at runtime).
  • It becomes a breaking change to change the name of a positional parameter. Even if you never intended it to be used as a parameter name in that way, there is no way to opt out. (Well, you can make it a private name, but that's ugly, and we don't want everybody making their positional parameters private just to not get trapped with a name that they want to change, effectively getting trapped with an ugly private name instead.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

2 participants