Skip to content

Private named parameter should apply to positional parameters too. #4479

@lrhn

Description

@lrhn

The current specification for private named parameters only applies to named parameters.

Only named parameters need a feature to make Foo({this._foo}); not be an error, but a positional parameter like Foo(this._foo); would also benefit from consistently treating the parameter name as foo.

The specification encourages doc-tools to display this._foo as foo in documentation, but that is only an encouragement, and even if followed, it's not enough.

I want to be able to write Foo(this._foo) and trust that the parameter is treated like it's named foo in every place the user may see that name, other than the actual source code of the constructor.
If I can't trust that, I'll likely keep writing Foo(int foo) : _foo = foo;. And I don't want to do that.

The places where that name is visible includes:

  • Documentation. I want to write [foo] to document the parameter in the constructor doc.
  • Runtime toString()s of:
    • the runtime function,
    • its runtime type, and
    • its static type, including where that gets propagated by inference.

I really do not want to expose any implementation detail in the public API.

So I propose that the renaming of the parameter also applies to positional initializing formals and field parameters. If they have a private declared name, which is the name of a private instance variable, the parameter name is the corresponding public name, and it should be enforced deep in our tools to ensure that every tool sees that name as the parameter name,

That does mean that the feature becoms potentially breaking, if someone has Foo(this._foo, int foo) : _bar = foo today, because then the _foo and foo would now conflict.

There are two ways to address that:

  • Tough, don't do that. You'll have to rename one of the parameters (and if the latter is named, then you may need to rename the instance variable, but that's probably a good thing since foo seems to mean something else here.)
  • You only get a public named parameter if there is no conflict. For a privately named initializing formal, that would still cause an error, because now its parameter name is still private. For a positional parameter, Foo(this._foo, int.foo) would keep working, and the parameter name of this._foo would still be _foo.

The former is simpler to explain. The latter is less breaking.

I still think it's worth it.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions