Skip to content

Commit aca410c

Browse files
authored
Revise "Private Named Parameters". (#4475)
Revise the motivation section for "Private Named Parameters". Fix version number and add section on super parameters. Fix #4471.
1 parent ddbc158 commit aca410c

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

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

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Author: Bob Nystrom
44

55
Status: In-progress
66

7-
Version 0.1 (see [CHANGELOG](#CHANGELOG) at end)
7+
Version 0.2 (see [CHANGELOG](#CHANGELOG) at end)
88

99
Experiment flag: private-named-parameters
1010

@@ -74,11 +74,8 @@ its library. Privacy is only meaningful for declarations that could be accessed
7474
from outside of the library: top-level declarations and members on types.
7575

7676
Local variables and parameters aren't in scope outside of the library where they
77-
are defined, so privacy doesn't come into play. Except, that is, for named
78-
parameters. A *named* parameter has one foot on each side of the function
79-
boundary. The parameter defines a local variable that is accessible inside the
80-
function, but it also specifies the name used at the callsite to pass an
81-
argument for that parameter:
77+
are defined, but named parameters can be referenced from outside of the library.
78+
This raises the question of how to interpret a private named parameter:
8279

8380
```dart
8481
test({String? _hmm}) {
@@ -90,17 +87,14 @@ main() {
9087
}
9188
```
9289

93-
A public function containing a named parameter whose name is private raises
94-
difficult questions. Is there any way to pass an argument to the function from
95-
outside of the library? If the parameter is required, does that mean the
96-
function is effectively uncallable? Or do we not treat the identifier as private
97-
even though it starts with an underscore if it happens to be a parameter name?
90+
Should this be allowed? And if so, do we treat this as a named parameter which
91+
can only be called from within the defining library?
9892

99-
The language currently resolves these questions by routing around them: it is a
100-
compile-time error to have a named parameter with a private name. Users must use
101-
a public name instead. For most named parameters, this restriction is harmless.
102-
The parameter is only used within the body of the function and its idiomatic for
103-
local variables to not have private names anyway.
93+
The language currently resolves this by saying that it is a compile-time error
94+
to have a named parameter with a private name. Users must use a public name
95+
instead. For most named parameters, this restriction is harmless. The parameter
96+
is only used within the body of the function and it is idiomatic for local
97+
variables to not have private names anyway.
10498

10599
### Initializing formals
106100

@@ -349,6 +343,34 @@ corresponding field private and that the argument should be the public name. The
349343
first time a user tries to call one of these constructors the wrong way, we can
350344
teach them the feature.
351345

346+
### Super parameters
347+
348+
We allow private named parameters for initializing formals and (assuming primary
349+
constructors exist), declaring parameters. What about the other special kind of
350+
constructor parameter, super parameters (the `super.` syntax)?
351+
352+
Those are unaffected by this proposal. A super parameter generates an implicit
353+
argument that forwards to a superclass constructor. The super constructor's
354+
argument name is always public, even if the corresponding constructor parameter
355+
uses this feature and has a private name. Thus, super parameters continue to
356+
always use public names. For example:
357+
358+
```dart
359+
class Tool {
360+
int _price;
361+
362+
Tool({this._price}); // Private name here.
363+
}
364+
365+
void cheapTool() => Tool(price: 1); // Called with public name.
366+
367+
class Hammer extends Tool {
368+
Hammer({super.price}); // And thus call with public name here too.
369+
}
370+
371+
void pricyHammer() => Hammer(price: 200);
372+
```
373+
352374
## Static semantics
353375

354376
An identifier is a **private name** if it starts with an underscore (`_`),
@@ -493,6 +515,7 @@ can help users learn the feature.
493515
### 0.2
494516

495517
- Add section about concerns for learnability and mitigations.
518+
- Add section on super parameters.
496519

497520
### 0.1
498521

0 commit comments

Comments
 (0)