dart-lang / language

Design of the Dart language
Other
2.67k stars 205 forks source link

Create Auto Properties in Dart #462

Open feinstein opened 5 years ago

feinstein commented 5 years ago

C# has auto properties which make creating public getters and private setters really easy, like public string Example { get; private set; }

I would like to suggest that we have something similar in Dart, like this:

int get _set count = 5;

This code would be equivalent to what we have to do now:

int _count = 5;
int get count => _count;
miyoyo commented 5 years ago

To be fair, the length difference between C#'s notation and Dart's current notation is almost indistinguishible here.

public string Example { get; private set; }
int _count = 5; int get count => _count;

Even then, the proposed notation is not that glanceable

List<int> counting = [];
int get _set count = 5;
final int counted = 21;

This easily gets lost in the sea of code, that might probably confuse newcomers quite easily.

lrhn commented 5 years ago

Dart uses names to distinguish private and public members, and nowhere does it change a source identifier from one to the other. This syntax would introduce a field and a setter named _count, which is a name that doesn't occur in the source.

Not saying it can't be done, or that I haven't wished for it often myself, but it's a subtle rewrite of the source code which may be lost on readers.

Maybe we could use some other syntax. Say:

int _x { get x; }

This introduces a field named _x along with an extra implicit getter named x. You could do int _shared {get foo; get bar; set bar; } and have extra implicit setters and getters for the field of any names. (There's still be a _shared getter, and setter because the field is not final).

This does conflict with suggested syntax for declaring abstract getters and setters: int foo {get; set;}, which would declare abstract an foo getter and setter, and int foo{get => _foo, set(value) { _foo = value; }} which would declare a concrete foo getter and setter.

feinstein commented 5 years ago

I think this syntax further complicates things and the problem of having a _x that's not declared in code is not the end of the world. People don't use _ with variable names that already exist, and if they do, the compiler could just raise a warning, or raise it if they declare the variable again themselves.

C# creates the auto properties by using backing fields that can be accessed in code, its not recommended that you try to use them, but they are there and I have never seen anyone having a problem with it.

feinstein commented 5 years ago

(sorry, I accidentally tapped the "comment and close button" while commenting on my phone).

feinstein commented 5 years ago

As for @miyoyo comment on length, I think some syntaxes require more "mindful context-switch", where we shift our focus a bit, and it can be annoying. Like "ok now I create this variable as a getter, oh and I have to create this private-backing filed here, ok now I go back to what I was doing".

Although mathematically the declarations might be very close, psychologically they are not and this small context-switch is just annoying.

mockturtl commented 5 years ago

"ok now I create this variable as a getter, oh and I have to create this private-backing filed here, ok now I go back to what I was doing".

There's a lint for that: https://dart-lang.github.io/linter/lints/unnecessary_getters_setters.html

feinstein commented 5 years ago

That lint is just for the case where there's an unnecessary getter or setter, but in my example I am specifying a necessary private setter and a necessary public getter.

mockturtl commented 5 years ago

necessary private setter

I think I see: in C#, a "private setter" provides write access to the implicit backing field. It's equivalent to an explicit backing field?

https://stackoverflow.com/a/3847982

feinstein commented 5 years ago

Precisely.