@@ -42,6 +42,13 @@ class House {
4242}
4343```
4444
45+ Calls to the constructor are unchanged and continue to use the public argument
46+ names:
47+
48+ ``` dart
49+ House(windows: 5, bedrooms: 3);
50+ ```
51+
4552This proposal harmonizes with (and in a couple of places mentions) the [ primary
4653constructors] [ ] proposal. When combined with that proposal, the above example
4754becomes:
@@ -268,6 +275,79 @@ class House({
268275});
269276```
270277
278+ ### Concerns
279+
280+ This proposal makes the language implicitly convert a private named parameter
281+ into the verbose pattern users do today where they declare a public named
282+ parameter and explicitly initialize the private field from it:
283+
284+ ``` dart
285+ class C {
286+ int? _variable;
287+
288+ C({int? variable}) : _variable = variable;
289+ }
290+ ```
291+
292+ While verbose, this code has the advantage of being very clear what's going on.
293+ A reader can see that the argument name they must use at the callsite is
294+ ` variable ` , the field is named ` _variable ` , and the latter is initialized from
295+ the former.
296+
297+ Discarding the ` _ ` implicitly may be confusing for users. If a user sees a class
298+ like:
299+
300+ ``` dart
301+ class C({int? _variable}) {}
302+ ```
303+
304+ They may try to call it like ` C(_variable: 123) ` and be confused that it doesn't
305+ work. There's nothing in the code hinting that the ` _ ` is removed from the
306+ argument name.
307+
308+ In general, we try to design features that are both useful once you know
309+ them and intuitive to learn in the first place. This feature is helpful for
310+ brevity once you know the "trick", but it's opaque when it comes to learning.
311+ This is a real concern with the feature, but I believe the brevity makes it
312+ worth the learnability cost.
313+
314+ We mitigate confusion here in a couple of ways:
315+
316+ #### Only allow the syntax where it's meaningful
317+
318+ At the language level, this proposal only allows ` _ ` in a named parameter when
319+ doing so is * useful and meaningful* . It doesn't allow * any* named parameter to
320+ start with underscore, only a named parameter that declares or initializes a
321+ private instance field.
322+
323+ A private named parameter * looks weird* since privacy makes little sense for an
324+ argument name and makes even less sense for the local parameter variable. (We
325+ already have a lint that warns on using ` _ ` for local variable names since it
326+ accomplishes nothing.)
327+
328+ If a user sees ` _ ` on a parameter and is trying to figure out what's going on,
329+ they will reliably be in a context where that parameter is also referring to a
330+ field. If we're lucky, that may lead them to intuit that the privacy is for the
331+ field, not the parameter.
332+
333+ #### Provide a teaching error if they use ` _ ` for other named parameters
334+
335+ If a user tries to put ` _ ` before a named parameter that * isn't* an initializing
336+ formal or declaring parameter, it's an error. That error message can explain
337+ that it's forbidden * here* but that the syntax can be used to declare or
338+ initialize a private field.
339+
340+ #### Provide a teaching error if they use ` _ ` on the argument name
341+
342+ If a user sees a named parameter with a private name, they may try to call the
343+ constructor with that same private argument name, like ` C(_variable: 123) ` .
344+ When they do, this is always an error.
345+
346+ The error message for that can explain that the ` _ ` is only used to make the
347+ corresponding field private and that the argument should be the public name. The
348+ first time a user tries to call one of these constructors the wrong way, we can
349+ teach them the feature.
350+
271351## Static semantics
272352
273353An identifier is a ** private name** if it starts with an underscore (` _ ` ),
@@ -396,8 +476,23 @@ initializing formal with the private name.
396476Since there's no reason to * not* prefer using an initialing formal in cases
397477like this, it probably makes sense to have a lint encouraging this as well.
398478
479+ ### Good error messages when users misuse this feature
480+
481+ Since this feature likely isn't as intuitive as we hope to be, error messages
482+ are even more important to help users understand what the language is doing and
483+ getting them back on the right path.
484+
485+ The [ Concerns] [ ] section suggests two error cases and how good messaging there
486+ can help users learn the feature.
487+
488+ [ concerns ] : #concerns
489+
399490## Changelog
400491
492+ ### 0.2
493+
494+ - Add section about concerns for learnability and mitigations.
495+
401496### 0.1
402497
403498- Initial draft.
0 commit comments