Open eernstg opened 3 months ago
I feel about this the same as I do #4009 - I don't think it will come up often enough to matter from a user perspective, the vast majority will never know either way what we decide.
This one in particular sounds like it has a lot more special cases though, which we would have to specify and the teams would then have to implement.
If we think the specification/implementation costs are near zero though, then sure.
There are several ways to approach this. The minimal requirement is that inside an augmenting function body (including variable initializer, so code, not declaration) you can use augmented
in a single allowed way (assign to in setters, invoke in functions, read in getters/variable initializers, execute in constructors, same as today).
If that is possible, anything else is us tweaking the edges.
We can choose to:
augmented
is an identifier that is implicitly in scope in the function bodies of augment
ing declarations. If you choose to shadow it, then that's your perogative. (It's in the body only, so parameters are unaffected, it's like an implicit parameter with special rules for how it can be used.) augmented
becomes an operator (reserved word) in the scope of bodies of augmenting declarations, like this
. It is still in scope inside nested functions, just like this
/super
. Still does not affect parameters. augmented
becomes a reserved word throughout the declaration of an augmetning declaration, covering also the parameter list, type parameters and return types. I see no benefit from this, other that preventing you from declaring a parameter named augmented
that you can't access. (You'll figure that out soon enough.)augmented
becomes a reserved word only inside the immediate body of an augmenting declaration, but not inside further nested functions, like await
in an async
function. I'd prefer to not do that, because it prevents some reasonable uses. I prefer to have it work more like this
/super
.Of these, I think 1 and 2 have the best usability and scope. Whether we allow you to shadow the name is a detail. It can be surprising if you do it, but you can shadow num
, dynamic
and identical
so it's not like you don't have foot-guns otherwise.
Going for 1 means you can use augmented
in other ways, like as a selector or named parameter name. That's nice.
But it also means there is no way to access a parameter named augmented
, which sad.
Extending the scope to the parameter list brings no benefit. May cause confusion.
If we allow non-constant default-value expressions, then we could make augmented
available in those, but I'd be much happier if we don't.
The one thing extending the scope to the parameter list does is to prevent a parameter named augmented
.
That doesn't help anyone. It means you can't agument a method named augmented
, or with a named parameter named augmented
.
(We could do #271, which I'd let you treat a reserved word as a plain identifier, or at leas a built-in identifier, allowing you to write fx \augmented
to refer to the named parameter. That works if we go for option 2. Won't work with option 1 where augmented
is already an identifier that shadows the parameter. And with escapes, you can do selectors too: foo.\augmented()
.)
TL;DR: My suggestion is that we make augmented
be a reserved word like this
and super
, which is in scope inside the body of an augmenting function body or augmenting variable initializer, not their parameter lists or types. Like this
and super
, and unlike await
, it can be used inside nested functions.
This is a simple and well-delimited scope, it's easy to determine where it starts, and it does not affect anything outside of the scope where augmented
can be used.
Which is part of this proposal, in that it allows it as a parameter name of the augmenting function, but not as a named argument name inside the function body. (I'd go for #271 to allow the rest.)
Maybe we should just go back to augment.super
instead :grin:
TL;DR: My suggestion is that we make
augmented
be a reserved word likethis
andsuper
, which is in scope inside the body of an augmenting function body or augmenting variable initializer, not their parameter lists or types. Likethis
andsuper
, and unlikeawait
, it can be used inside nested functions.
This sounds fine to me
The augmentation feature specification makes it an error to use
augmented
as an identifier expression anywhere inside an augmenting declaration.In https://github.com/dart-lang/language/issues/4009, it is discussed whether we should allow
augmented
to be used as an identifier expression in some cases (in particular, inside a non-augmenting member declaration which is in turn inside an augmenting type-introducing declaration, e.g.,augment class C { void foo() { ... augmented ...} }
).We do have the opportunity to allow augmented to be used in several other ways that aren't identifier expressions:
foo(augmented: true)
.void foo({augmented = 0})
.(1, augmented: 'Certainly!')
.e.augmented
. This covers cascades as well, e.g.,e..augmented
.C.augmented(5)
.augment class C { int i; C.augmented(this.i); }
.augment class C { void augmented() {}}
.In all cases there is no way the given occurrence of
augmented
could be an application of the feature that allows us to call the augmented declaration or evaluate the initializing expression of the augmented declaration. It is evident from the syntax that we have one of these cases (in other words, we don't have to look up anything in order to detect that we have one of these cases).In other words, we could allow these usages anywhere inside an augmenting declaration.
The argument in favor of doing this would be that it is possible and may be convenient (and the workaround which is needed otherwise includes inconvenient things like top-level wrapper functions that will call the function that takes the named argument, etc, if there even is a workaround).
The argument against doing this is that it is likely to be a source of confusion that
augmented
can be anything other than an invocation of the augmented entity inside an augmenting declaration.If we decide in #4009 that
augmented
as an identifier expression inaugment class C { void foo() { ... augmented ...} }
is simply a reference to a declaration namedaugmented
which is in scope then I believe we should also allow the usages mentioned above.It is possible that the specification already implies that we can use
augmented
in some of these cases (many of them are certainly errors currently, but there could be loopholes). However, it will probably be useful to discuss it in more detail in any case.@dart-lang/language-team, WDYT?