Skip to content

Commit 2720387

Browse files
authored
Clarify some vague text in "Private Named Parameters". (#4478)
Clarify some vague text in "Private Named Parameters". Fix #4472. Fix #4473.
1 parent c5c531a commit 2720387

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

working/2509-private-named-parameters/feature-specification.md

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ then the name affects *three* places in the program:
105105
1. The name of the parameter variable inside the constructor initializer list.
106106
(Inside the constructor *body*, it's the instance field that is in scope.)
107107

108-
2. The name used to pass an argument at the callsite.
108+
2. The name used to pass an argument at the call site.
109109

110110
3. The name of the corresponding instance field to initialize with that
111111
parameter.
@@ -138,7 +138,7 @@ This creates a tension. A user may want:
138138
unusual initializer syntax, and makes it clear to a reader that the field
139139
is directly initialized from that parameter.
140140

141-
They want encapsulation, readability at callsites, and brevity in the class
141+
They want encapsulation, readability at call sites, and brevity in the class
142142
definition, but because of the compile-error on private named parameters, they
143143
can only [pick two][].
144144

@@ -226,10 +226,11 @@ encapsulation.
226226
227227
## Proposal
228228
229-
The basic idea is simple. We let users use a private name in a named parameter.
230-
The compiler removes the `_` from the argument name but keeps it for the
231-
corresponding initialized or declared field. In other words, we do exactly what
232-
users are doing by hand when they write an initializer like:
229+
The basic idea is simple. We let users use a private name in a named parameter
230+
when the parameter also initializes or declares a field. The compiler removes
231+
the `_` from the argument name but keeps it for the corresponding field. In
232+
other words, we do exactly what users are doing by hand when they write an
233+
initializer like:
233234
234235
```dart
235236
class House {
@@ -285,7 +286,7 @@ class C {
285286
```
286287

287288
While verbose, this code has the advantage of being very clear what's going on.
288-
A reader can see that the argument name they must use at the callsite is
289+
A reader can see that the argument name they must use at the call site is
289290
`variable`, the field is named `_variable`, and the latter is initialized from
290291
the former.
291292

@@ -311,9 +312,9 @@ We mitigate confusion here in a couple of ways:
311312
#### Only allow the syntax where it's meaningful
312313

313314
At the language level, this proposal only allows `_` in a named parameter when
314-
doing so is *useful and meaningful*. It doesn't allow *any* named parameter to
315-
start with underscore, only a named parameter that declares or initializes a
316-
private instance field.
315+
doing so is *useful and meaningful* because it declares or initializes a private
316+
instance field. If the named parameter does neither of those, this proposal
317+
still prohibits the parameter from having a private name.
317318

318319
A private named parameter *looks weird* since privacy makes little sense for an
319320
argument name and makes even less sense for the local parameter variable. (We
@@ -389,22 +390,26 @@ with private name *p* in constructor C:
389390

390391
* If *p* has no corresponding public name *n*, then compile-time error. *You
391392
can't use a private name for a named parameter unless there is a valid
392-
public name that could be used at the callsite.*
393+
public name that could be used at the call site.*
393394

394395
* If any other parameter in C has declared name *p* or *n*, then
395396
compile-time error. *If removing the `_` leads to a collision with
396397
another parameter, then there is a conflict.*
397398

398-
* Otherwise, the name of the parameter in C is *n*. *If the parameter is
399-
named, this then avoids the compile-time error that would otherwise be
400-
reported for a private named parameter.*
399+
If there is no error then:
401400

402-
* The name of the local variable in the initializer list scope of C is *p*.
403-
*In the initializer list, the private name is used. Inside the body of the
404-
constructor, uses of *p* refer to the field, not the parameter.*
401+
* The parameter name of the parameter in the constructor is the public name
402+
*n*. This means that the parameter has a public name in the constructor's
403+
function signature, and arguments for this parameter are given using the
404+
public name. All uses of the constructor, outside of its own code, see only
405+
the public name.
405406

406-
* If the parameter is an initializing formal, then it initializes a
407-
corresponding field with name *p*.
407+
* The local variable introduced by the parameter, accessible only in the
408+
initializer list, still has the private name *p*. *Inside the body of the
409+
constructor, uses of _p_ refer to the instance variable, not the parameter.*
410+
411+
* The instance variable initialized by the parameter (and declared by it, if
412+
the parameter is a field parameter), has the private name *p*.
408413

409414
* Else the field parameter induces an instance field with name *p*.
410415

@@ -458,14 +463,21 @@ further ideas for additional warnings, lints, and quick fixes.
458463

459464
Authors documenting an API that uses this feature should refer to the
460465
constructor parameter by its public name since that's what users will pass.
461-
Likewise, docs generator like [`dart doc`][dartdoc] should document the
466+
Likewise, doc generators like [`dart doc`][dartdoc] should document the
462467
constructor's parameter with its public name. The fact that the parameter
463468
initializes or declares a private field is an implementation detail of the
464469
class. What a user of the class cares about is the corresponding public name for
465470
the constructor parameter.
466471

467472
[dartdoc]: https://dart.dev/tools/dart-doc
468473

474+
The language already allows a *positional* parameter to have a private name
475+
since doing so has no effect on call sites. Doc generators are encouraged to
476+
also show the public name for those parameters in generated docs too. The fact
477+
that the positional parameter happens to initialize or declare a private field
478+
is again an implementation detail that shouldn't appear in the API or
479+
documentation.
480+
469481
### Lint and quick fix to use private named parameter
470482

471483
There is currently a lot of code in the wild like this:

0 commit comments

Comments
 (0)