dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.06k stars 1.55k forks source link

Add public and private access modifiers to language #33383

Closed Ing-Brayan-Martinez closed 6 years ago

Ing-Brayan-Martinez commented 6 years ago

Hello everyone, I've been analyzing the answers they gave me in issue #33104 33104, and I'll summarize them in a single proposal, which I consider a necessity and the most important, since the translation is not exact, I'll explain it with a couple of examples:

class CounterState extends State<Counter> {

  private int counter = 0;

  private void increment() {
    setState(() {
      this.counter++;
    });
  }

  private void decrement() {
    setState(() {
      this.counter--;
    });
  }

  public Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new RaisedButton(
          onPressed: this.increment,
          child: new Text('Increment'),
        ),
        new RaisedButton(
          onPressed: this.decrement,
          child: new Text('Decrement'),
        ),
        new Text('Count: $counter'),
      ],
    );
  }
}
class Person {

  private String firstName; 
  private String lastName;  
  private int age;        

  Person(this.firstName, this.lastName, this.age);

  public Map<String, dynamic> asMap() {
    return {
      'firstName': this.firstName,
      'lastName': this.lastName,
      'age': this.age
    };
  }

  String get firstName => this.firstName;
  String get lastName => this.lastName;
  int get age => this.age;
}

void main() {
  final Person x = new Person("Brayan", "Martinez", 23);

  print(x.firstName)
  print(x.asMap().toString());
}
vsmenon commented 6 years ago

Retitled to highlight the request.

zoechi commented 6 years ago

What's the problem this change would solve?

Ing-Brayan-Martinez commented 6 years ago

It's a good question, I think it's necessary, this proposal comes mainly for two reasons.

The first one is about the adoption and use of this technology, this I will explain in the following list:

The second reason, seeing it from a more technical point of view, is to make a language more secure, standard, nice to the programmer, with business vision and general purpose, this will be explained better in the following list:

Well I hope to convince and have been able to justify the proposal very well I hope this is a reality, what I have left is to give a greeting from here

zoechi commented 6 years ago

Sounds like personal preference. I doubt this is good enough a reason to change a language that is around for about 6 years. Also there are lots of people who prefer how it is today. I find public and private extremely verbose and would consider the change you propose a pain.

lrhn commented 6 years ago

It's not the first time this has been requested, but we have no current plan to add such keywords.

There is a reason Dart does not use class based privacy. Dart allows dynamic invocations. If you write dynamic x = someObject(); x.foo; then the foo access does not know the class of the object in x. It must work independently of that. Now, if x has a class with a private foo, should that function then be found? That depends on whether the access x.foo is inside that class. If it's protected, then it depends on whether the access is inside a subclass of the declaring class. That adds a lot of overhead to dynamic accesses. It's not impossible, but it's just not something that the Dart language is well suited for.

The library based privacy that Dart has is allows us to syntactically detect private member accesses, and use renaming per library to allow a more efficient implementation of dynamic access.

If we ever add some other sort of privacy, it's more likely to be instance based than class based. That means that you can only access such members through this or super, which ensures that we always know the type of the receiver and we avoid dynamic accesses.

Ing-Brayan-Martinez commented 6 years ago

What a shame that this request is not taken into account, this was a necessary requirement to take the decision to create an ERP on this platform, I speak to you as an investor and it is unfortunate that it ends well, I will have to look at the copetence like Java or TypeScript

fabiocarneiro commented 5 years ago

My sincere apologies for commenting on a closed issue from 2018.

I would like to see that too. It would make Dart almost perfect language.

In my opinion, at least the _ could have been named private (or package private). It's not only very ugly to use _, but also not verbose and not adoption friendly. Most of the developers working in other languages know what private means, but hardly everyone new to Dart can be sure what _ means without reading docs.

It sacrifices verbosity in favor of fewer letters to type, when in fact, most of the time on development is not spent on pressing keys on the keyboard but thinking about what to type. The difference between typing 1 character, to ~15 is not relevant to the project development time, even if you multiply it to 50000.

I did read and understood the concerns raised by @lrhn, but I find very useful to have the instance visibility concept available. I think the concern raised was mostly about how to detect visibility when you have inheritance. That would not be a problem if the language didn't allow inheritance (not even mixin, but compile time paste with traits) but only composition and interfaces.

If I was maintaining Dart, I would still consider adding package private as a minor and marking _ as deprecated, so in the next major or some years from now it could be removed.

eernstg commented 5 years ago

I think it's important to note that this is actually not about syntax. You could choose lots of different syntactic forms for the same thing, but it's the underlying structure that matters.

When privacy is indicated in the name of a class member (for instance, using _foo rather than foo) then it can be enforced independently of static typing, essentially with no performance cost. This is the approach that Dart uses.

When privacy is indicated by a keyword in the declaration (say, private) and is invisible at call sites, it would be prohibitively expensive to enforce privacy for dynamic invocations.

It would also cause ambiguities, because you can have, say, two superclasses of the dynamic type of the receiver, each of which adds a private foo. They may have completely incompatible signatures and purposes, and, presumably, you would want to call the foo that you happen to know about (whereas the existence of the other one might come as a complete surprise), but you might just as well get the surprise.

It would be detrimental to modular development to say that it's an error for two classes with a subclass relationship to add a private method with the same name (because then you'd have to know about all private methods in your class hierarchy, including the ones that are written and maintained by someone else).

So you could claim that it's all about having a well-defined semantics for dynamic method invocations (and perhaps you would add "and I don't care about having dynamic at all"). But unless you want to ban dynamic invocations 100% from all your software (noting that Java and C# added support for some dynamic features), the fact that you cannot enforce privacy takes away a substantial amount of software robustness:

If you create a complex library L, and anybody who wants to do so can go in and fiddle with the values of your private variables and call your private methods etc, then I think it might be harder for you to maintain L, and to interpret bug reports and so on. OK, you have a private variable called foo, and the client's huge program does have a dynamic invocation of a setter named foo, but how do you know that the client is touching your foo and messing up some invariants that you need to maintain? It only takes one dynamic invocation in a huge program to raise that question.

chornbe commented 5 years ago

No idea why scope wouldn't be included and explicit. Flutter & Dart have some great things going on, but the things that are... odd?... are REALLY odd. And some of its verbosity for simple things is a little silly, while CHOOSING to leave out explicit scoping just seems like a poor choice. Same with inner classes. shrug

Ing-Brayan-Martinez commented 5 years ago

PHP is a very common scripting language used in the industry, in my opinion it is a worthy example to follow for the syntax of public and private the way of doing things in php is very intuitive and is very similar to java or c# with less verbosity of course, PHP continues to triumph in web development where the issue of verbosity and framework is attacked much like laravel hasen that php is very nice

fabiocarneiro commented 5 years ago

@eernstg

I think it's important to note that this is actually not about syntax. You could choose lots of different syntactic forms for the same thing, but it's the underlying structure that matters.

If the underlying structure is what matters, let's choose a way to express the concept that is more familiar to everyone and looks less like an identifier naming standard.

It would also cause ambiguities because you can have, say, two superclasses of the dynamic type of the receiver, each of which adds a private foo. They may have completely incompatible signatures and purposes, and, presumably, you would want to call the foo that you happen to know about (whereas the existence of the other one might come as a complete surprise), but you might just as well get the surprise.

I don't buy this argument. If it is private you are not supposed to call or know it exists from an external perspective.

you'd have to know about all private methods in your class hierarchy, including the ones that are written and maintained by someone else

You don't have to know all private methods in your class hierarchy. That is not an issue in any OOP language and I don't see why it would be in Dart.

OK, you have a private variable called foo, and the client's huge program does have a dynamic invocation of a setter named foo, but how do you know that the client is touching your foo

I think what you are understanding by private is what I understand by protected. Are you assuming private members would be accessible by inheriting classes?

This makes a lot of difference in the discussion because if private is only available within the class, it should never be accessible even if done dynamically.

I think as @Ing-Brayan-Martinez mentioned, you should take a look at how it works on PHP (and private works the same way in Java, Kotlin). I quote from PHP manual:

I think Dart does not need to support (as described above) such protected behavior

Maybe we can avoid inheritance at all in favor of composition?

eernstg commented 5 years ago

@fabiocarneiro wrote:

let's choose a way to express the concept that is more familiar

I understand that this kind of familiarity can be seen as attractive (especially for developers who are working in a highly heterogeneous environment), but at this point it would be a massively breaking change to switch from the _ name prefix to a private modifier in Dart. The name prefix ensures that it's obvious at use sites which member accesses are private, which I think is useful, and others might consider it more important to avoid the visual noise of _. But let's separate the syntax from the semantics (the syntax discussion will never end, anyway ;-).

It would also cause ambiguities ..

.. If it is private you are not supposed to call or know it exists

Dart private methods support overriding because the scope of privacy is the library (so you can have a class hierarchy with normal method overriding applied to private methods). In that sense, Dart privacy is "module privacy", somewhat similar to the Java notion of being package private.

This means that you cannot just choose to jump directly to the statically known implementation of a given private method, and this means that there must be some mechanism that enforces the distinction between the private foo method from library L1 and another private method foo from library L2 (that may be present in the same instance because a class from L2 can have a class from L1 as its superclass).

When the _name approach to privacy was chosen (long time before I joined the Dart team) it was a major factor that the strict enforcement of this distinction could be implemented with no run-time performance penalty. (Basically, names of the form _foo can be mangled to include a unique part denoting the enclosing library, in declarations as well as invocations; that step must be applied to every occurrence of a private name, and if it is applied to any non-private name then it breaks the semantics. Of course, the language specification describes this in very different terms, but the name mangling approach is a very good model for understanding how it works.).

In PHP, the privacy scope is the class, and it's sufficient to compile private methods such that they check that the call site is in the same class (and for protected: that the receiver of the caller has a type which is a subtype of the enclosing class). But even that is a performance penalty, and I don't think such an approach (had it worked in Dart) would have been accepted for Dart. The fact that PHP privacy violations arise at run time demonstrates that there is a dynamic check, and that never has a cost of zero.

So my point was that we cannot accept this kind of ambiguity, but with a private modifier approach we will have it unless we accept a performance penalty for privacy related checks.

I think what you are understanding by private is what I understand by protected.

Protected is usually associated with the subclass hierarchy and unrelated to the module structure (in Dart: library structure), but you are right that privacy in Dart does include overriding relationships, which is not the case for class-based privacy.

So the source of confusion may be that what I understand by private (in this context) assumes a relationship with privacy in Dart.

I think Dart does not need to support (as described above) such protected behavior

If this is a proposal for dropping the current notion of privacy in Dart (library scoped privacy) and replacing it by a class scoped notion of privacy then we're looking at an even more massively breaking change.

On the other hand, it would be possible to add a completely new notion of class scoped privacy for members, and it could use a private modifier. The protection against (statically checked as well as dynamic) invocations of such a method from anywhere outside the class could be achieved by name mangling, and that could also be used to prevent overriding. The compiler would be allowed to compile call of such methods into a direct jump.

class C {
  C next;
  private int foo() => next != null ? next.foo() : 42;
}

var x1 = new C().foo(); // Compile-time error.
var x2 = (new C() as dynamic).foo(); // Dynamic error.

This notion of privacy would compete with another one where invocations of private methods are restricted to have the receiver this (so this is object scoped privacy). It's not obvious to me which variant of those is more useful in practice (and maybe the answer is just "that depends"), and it's also not obvious to me that we'd want to have a large number of mechanisms in this area. So that's a delicate topic.

Finally, it might seem more natural for Dart to build on top of the existing privacy mechanism (and enforce that private methods have names of the form _..., because they are subject to the usual library privacy constraints and guarantees, plus some extras). But I won't even mention that. ;-D

fabiocarneiro commented 5 years ago

Thanks for the patience, and I need to say that I love this discussion.

In the Dart context, Private means something else, but for me and others, when we request this feature, we always mean "object scoped privacy"

Java package-private is also probably not the best name for this concept of visibility within a library. The absence of the modifier is what declares Package-private in java, and if you compare to the other modifiers, it behaves much more similarly to Protected than to Private. Protected is the same, but also allow visibility from other packages. That said, If I were giving it a name on the Java context, I would call it package-protected instead of package-private.

The same reasoning can be applied to Dart, as the _ is closer to protected (or package-protected) than to private. Updating that in the documentation would probably be beneficial to avoid new developers to have different expectations for the _. As an example, I would propose something like the following:

In Dart, there is no concept of private visibility, but package-protected can be defined by _.

That said, what all of us are requesting here is the introduction of a private keyword and it can be a completely new feature. If it wouldn't imply any performance impact, the _ can be left untouched, and there is no backward compatibility break.

Then the question is: Can this private modifier be implemented without performance impact? The way I see, it is a very straightforward process to detect in compile-time the call to Private members from external places. In the Dynamic contexts, I can see there might be a check to see if the member is visible or not, but isn't that the same check as seeing if it exists or not? Isn't the difference that now the list of existing methods would be a list of visible methods?

For me, the source of your concerns would be the introduction of a "protected" keyword, and that is NOT what we are asking.

One important factor here is also not only the performance but how likely people are to adopt the language. It is true that Dart is a huge success, but I also can see a lot of people complaining about its design choices. In the end, if people are not willing to adopt the language, its performance does not matter. In the end, we can all be writing code in assembly to achieve such great performance.

eernstg commented 5 years ago

Thanks!

Tomorrow is a holiday here, so I'll just add a short remark and then go home ;-)

A private modifier could be implemented as a name mangling scheme which makes it impossible to call a private method foo outside the class C that declares it, even dynamically.

The tricky part is that this would make it hard to deal with (e as dynamic).foo() inside C: It might be intended to call the private method on that receiver, and if we mangle foo for that call then it will indeed call that private method on an instance of C or any subclass thereof, and it won't call any other private method (so the "no overrides" still holds). But it might also be intended to call some other (non-private) method named foo. So if we're willing to somehow choose explicitly at the call site, for a dynamic invocation, whether it's a private or a public call, then we can obtain a consistent semantics. Otherwise that corner is a mess. ;-)

marcglasberg commented 4 years ago

If you love clean-code like me, then you hate the _. It makes code difficult to read. Also, I don't see many uses for dynamic (in regular Flutter code, at least). Me and my team never use it.

For me it would be enough if private worked for typed variables, and then be ignored for dynamic ones. It would be a way for you to access private variables if you wanted, much like today you can mark something as @protected but still access it if you want.

In other words, private and protected keywords could work just like @private and @protected annotations.

Or at least we could have a @private annotation: https://github.com/dart-lang/sdk/issues/41089

comm1x commented 4 years ago

Dart is going to add more type safety, and we don’t want to add access modifiers cause of dynamics?..

Guys, we are migrating to flutter from awesome Kotlin and Swift, not from stupid js. Dynamics is bullshit, nobody never use it in big production apps.

Stop being js and just add modifiers, instead of ugly _ and @protected

angelhdzmultimedia commented 4 years ago

Access modifiers, please.

You want more people to join Dart and Flutter? Show that you care about them. Access modifiers are an important part of Object Oriented Programming, and just saying "we prefer this way" just denote you are not about end users, but only about the closed community developers working on Dart/Flutter who take the naming decisions.

I have more poor naming decisions to point out, among them, Padding(padding), Opacity(opacity), instead of Padding(value), Opacity(value). Saying "the padding of the Padding" and "the opacity of the Opacity" is redundant, and we are supposed to be against redundancy.

I've read all the reasons for not using access modifiers and going the "everything is public, unless you use underscore" route. There are all non-sense.

Then, there are decorators (meta tags) to tell that something is protected... so, why going the meta tags route, instead, of, erm.... using private, public, protected keywords, like the rest of the OOP languages???

It's like saying "Hey, everyone, notice me! I'm different! Everyone else is going right, but I'm going left because...reasons! Durr durr!"

Like the comment above me: Stop being js and just add modifiers, instead of ugly _ and @Protected.

esenmx commented 4 years ago

We need a way to modify accessibility of classes because in favor of Flutter. I create too many widget classes and in huge projects being able to import anything from anywhere is not the best thing. Also I don't like the _ prefix because it's not very readable and slowing down the typing.

For me, the most obvious thing to have as functionality is having a way to modify accessibility scope of some classes into a specific folder. This is very common case IMHO, e.g. you have a Screen widget, there are state class(es) file(s) related to it, there are widgets related to it and goes on... I don't want to import anything from there to other Screen classes. I think this is very common concept every Flutter developer faces during development.

Golang has best design choices for this topic, you can borrow some concepts from it. Uppercase => public, not slowing down the typing. Don't wanna import anything from anywhere => create another package. But of course Dart should have its own way to handle this.

I may open a proposal for this.

shbi commented 3 years ago

@eernstg Thanks for all the info on why underscore was used. Wondering though, would it be a problem to leave underscore for modular privacy and implement class or instance privacy using a private keyword? Would that no longe require the name mangling and avoid a lot of the problems with dynamic as it won't be able to overwritten or called from outside the class?

eernstg commented 3 years ago

I think class privacy would have the same issues as library privacy. Instance privacy could presumably be enforced for dynamic invocations (say, when generating native code) by (1) checking whether the callee is instance private and, if so, (2) throwing unless the receiver in the previous activation record is the same as the receiver in the new activation record. However, that may not be cheap (for instance, the receiver may be stored in a register and may have spilled into any location of the previous activation record).

It would probably be more useful to decide up front that some kinds of access control will guarantee enforcement, so they can be used for optimizations and other "hard" purposes. Others are just used to emit diagnostic messages when it's known that there is a violation, and we accept that there can be a number of violations that won't be detected. The latter kind is useful as an aid in the approximate enforcement of certain software engineering properties.

lukemcdo commented 3 years ago

Absolutely wild that this is considered "closed not planned" considering its ramifications for development. If I want to create a private method that should not be used by other classes in the package I have no options in Dart except for communicating its private nature to team members. If nothing else, this also clutters code completions.

While no code is truly self-documenting, this absence means that Dart code cannot approach self-documenting.

chornbe commented 3 years ago

There’s always early 90s Visual Basic notation of “p__” on private variables.

FWIW I’ve decommissioned one flutter project this year. I think management is considering another for next year.

On Oct 24, 2020, at 4:13 PM, lmcdougald notifications@github.com wrote:

 Absolutely wild that this is considered "closed not planned" considering its ramifications for development. If I want to create a private method that should not be used by other classes in the package I have no options in Dart except for communicating its private nature to team members. If nothing else, this also clutters code completions.

While no code is truly self-documenting, this absence means that Dart code cannot approach self-documenting.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

tobega commented 3 years ago

Interesting that nobody has been able to give any concrete example as to what problem class privacy would solve. Seems to me that they just want to change Dart to work with their current coding practices rather than learn how to use Dart effectively.

In Java you have a class per file and things marked private are accessible only in that file. In Dart, each file is a library and anything with an underscore is only accessible in that file. ¯\(ツ)

comm1x commented 3 years ago

@tobega I believe such topic does not need examples. Everybody know what we are talking about. But if you want:

Instead of

User _user;
@Protected
Car car;

I suggest default syntax from C-family languages:

private User user;
protected Car car;

"they just want to change Dart to work with their current coding practices"

Some things are done well in other languages. We are not lazy, we are able to change our habits and practices. So we don't want to just change the language. I believe the approach with access modifiers from Kotlin/Swift/Java is more natural and more beautiful than "Hungarian notation" in Dart.

In android we write every member from "m", mUser for example (Google force this practice). And this is ugly, even if it written on Java or Kotlin. And the same with "_" prefixes and @Protected annotation in Dart.

tobega commented 3 years ago

"More beautiful" is an opinion not a fact. It is not convincing at all.

On Tue, 17 Nov 2020 at 21:09, Pavel Shorokhov notifications@github.com wrote:

@tobega https://github.com/tobega I believe such topic does not need examples. Everybody know what we are talking about. But if you want:

Instead of

User _user;

I suggest default syntax from C-family languages:

private User user;

"they just want to change Dart to work with their current coding practices"

Some things are done well in other languages. We are not lazy, we are able to change our habit's and practices. So we don't want to just change language. I believe approach with access modifiers from Kotlin/Swift/Java is more natural and more beautiful than "Hungarian notation" in Dart.

In android we write every member from "m" (mUser) for example (Google forced this practice). And this is ugly, even if it written on Java or Kotlin. And the same with "_" prefixes in Dart.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/dart-lang/sdk/issues/33383#issuecomment-729172771, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGACJ54S7XWAPJSSHR73BT3SQLJ7RANCNFSM4FD23YCQ .

tonyrbf96 commented 3 years ago

Haven't you seen double underscore in front of and behind Python's reserved methods? What's so ugly about that? I like the current way.

chornbe commented 3 years ago

Ugly or not isn’t a thing.

It’s about convection. Most programmers move from language to language out of necessity. Especially in the mobile space. Having some conventions and norms that are agnostic would be great.

Working in Lang du jour xyz is it private, module, friend, underscore, wrapped undescores, double wrapped underscores, and so forth.

Because of arbitrary choice by people who “have a better idea.”

But what do I know? I’ve only been moving from language to language for 35 years. Some kind of consistency in all that time would have been great.

On Dec 18, 2020, at 1:32 AM, Tony Raul Blanco Fernandez notifications@github.com wrote:

 Haven't you seen double underscore in front of and behind Python's reserved methods? What's so ugly about that? I like the current way.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

chornbe commented 3 years ago

Convention, that is.

On Dec 18, 2020, at 6:25 AM, Chris Hornberger chris.hornberger@icloud.com wrote:

 Ugly or not isn’t a thing.

It’s about convection. Most programmers move from language to language out of necessity. Especially in the mobile space. Having some conventions and norms that are agnostic would be great.

Working in Lang du jour xyz is it private, module, friend, underscore, wrapped undescores, double wrapped underscores, and so forth.

Because of arbitrary choice by people who “have a better idea.”

But what do I know? I’ve only been moving from language to language for 35 years. Some kind of consistency in all that time would have been great.

On Dec 18, 2020, at 1:32 AM, Tony Raul Blanco Fernandez notifications@github.com wrote:

 Haven't you seen double underscore in front of and behind Python's reserved methods? What's so ugly about that? I like the current way.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

fabiocarneiro commented 3 years ago

Haven't you seen double underscore in front of and behind Python

Mentioning the lack of support on something in another language as a justification to not have in Dart. Is that an argument? Imho Python is a very ugly language and a bad example to be followed.

What's so ugly about that

Why do we need to rely on conventions to do something that can be enforced on a language level? What if that one project the developer wasn't aware of or didn't care about the conventions? What is the benefit of having it as a convention?

It is not so much about being ugly, but it might actually be an important factor. Beautifulness is related to how easy the code is to be understood. Language adoption improves if the developer has more pleasure reading and writing code.

trulysinclair commented 3 years ago

I'm just here to add my personal opinion, coming from TypeScript/JavaScript, we have actually always used _ as a personal standard to imply private methods and functions that aren't meant to be exported. Then recently an official language amendment gave us # to directly specify private within the engine. TypeScript already provided public, static, and private but now # is separate even in TypeScript.

So with all that, the explicit _ being used instead of private I'm accustomed to, and many other JavaScript devs coming from React Native to Flutter greatly appreciate this decision to have _. I'd also like to point out, an underscore also takes up fewer characters in a line of code.

fabiocarneiro commented 3 years ago

we have actually always used _ as a personal standard

We who? I saw more js projects that don't follow that than ones that do.

official language amendment

That is what is being proposed here. I'm sure that when what you described was proposed in the javascript ecosystem, many argued it was not necessarily because the convention was enough.

underscore also takes up fewer characters in a line of code.

I think nobody would argue against shorter is better. But one visibility modifier is probably not enough. I think the ones advocating the C-like approach would be willing to compromise as long as we can find reasonable symbols for private, protected, and public, that behave in a similar way to other languages. Let's imagine ("_" for private, "%" for protected, and "@` for public).

What is often also considered important is how easy it will be for someone to expect the behavior by seeing the symbol. You have to agree that for someone that never used such symbols, "_" is a lot harder to predict than the word "private". If eventually, the language needs to be extended to support another type of visibility, another symbol would be needed...

I see a problem with Dart that _ and @Protected are not consistent, and _ does not behave the same way private behaves in other languages.

Last but not least, most of the time spent programming is not caused by the number of characters you type, but the time you spend thinking about the solution you are writing. With that in mind, writing "_" or "private" makes very little difference.."

For the sake of consistency and clarity, If we had to vote, I would probably still choose the written approach. But one thing that seems to be clear is that the majority does not like the current inconsistency with _ and @Protected, and many don't even know that _ actually means something else. We want to improve that situation.

chornbe commented 3 years ago

Once again, developers move from language to language. Consistency helps us all work better across various platforms. Why is this not obvious?

Also, typing underscores sucks.

On Jan 6, 2021, at 9:03 PM, Fábio Carneiro notifications@github.com wrote:

 we have actually always used _ as a personal standard

We who? I saw more js projects that don't follow that than ones that do.

official language amendment

That is what is being proposed here. I'm sure that when what you described was proposed in the javascript ecosystem, many argued it was not necessarily because the convention was enough.

underscore also takes up fewer characters in a line of code.

I think nobody would argue against shorter is better. But one visibility modifier is probably not enough. I think the ones advocating the C-like approach would be willing to compromise as long as we can find reasonable symbols for private, protected, and public, that behave in a similar way to other languages. Let's imagine ("_" for private, "%" for protected, and "@` for public).

What is often also considered important is how easy it will be for someone to expect the behavior by seeing the symbol. You have to agree that for someone that never used such symbols, "_" is a lot harder to predict than the word "private If eventually, the language needs to be extended to support another type of visibility, another symbol would be needed...

I see a problem with Dart that _ and @Protected are not consistent, and @Protected does not behave the same way protected behaves in other languages.

Last but not least, most of the time spent programming is not caused by the number of characters you type, but the time you spend thinking about the solution you are writing. With that in mind, writing "_" or "private" makes very little difference.."

For the sake of consistency and clarity, If we had to vote, I would probably still choose the written approach. But one thing that seems to be clear is that the majority does not like the current inconsistency with _ and @Protected, and many don't even know that @Protected actually means something else. We want to improve that situation.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

lukemcdo commented 3 years ago

Commenting that "_ takes less characters" does not make much sense considering that most environments can quickly adapt to auto-complete "pr" to "private." It really should not be a factor.

Underscore is frustrating because it's also often used in function signatures when an argument is not going to be used, and can be a compiler shortcut in other languages there as well! Will the compiler have a special case for this, too? I'd rather see keywords than random symbols in either of these compiler special cases.

comm1x commented 3 years ago

About shortness I also remind Objective-C, which used short + for static members.

-(void) someFn // instance fn
+(void) someFn // static fn

Short? - yes! Readable? Not.

chornbe commented 3 years ago

“rm -fR ~/developer/flutter/“ fixes these issues ;)

All kidding aside, I’ll take readable, predictable, standards-adherent coding over brevity every single day. I don’t need brevity for the sake of brevity. That’s the compiler’s job. Code should be short and small enough to do the job well and absolutely no smaller. We’re people.

This discussion is seemingly a waste of time, and the current standard of _ for these variables is just dumb. But clearly the flutter team has made a decision and has defended it. So that seems to be that.

On Jan 10, 2021, at 8:13 AM, Pavel Shorokhov notifications@github.com wrote:

 About shortness I also remind Objective-C, which used short + for static members.

-(void) someFn // instance fn +(void) someFn // static fn Short? - yes! Readable? Not.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

CharlVS commented 3 years ago

@eernstg I hope this thread represents a minority but I'd like to say thank you for engaging with the community regarding this issue. It was sad to see that very few counter-arguments were brought against your explanations and that it was rather a series of reiterances of the subjective/anecdotal views brought forward. I come from a full stack PHP/JS background and I'm learning Dart/Flutter/Firebase as a personal side-project. I've fully embraced all the conventions as I trust that all decisions you/Google make will be substantiated and for the benefit of the language even if I do not agree with them.

To those stumbling upon this thread whilst looking at getting into Dart, please check out the Dart language tour as it will give you an understanding of Dart's quirks as well as what you will be getting into before investing your time.

lukemcdo commented 3 years ago

Frankly Charly, that's a pretty demeaning view of things. It's possible to be grateful for a product and also critical of it. This is an area that certainly warrants critique and scrutiny.

Also, that's a weird sentiment with regards to trusting that a product is currently being developed as best for the language. This is just some PM being excessively opinionated on an issue that either will get fixed when he moves on, or ingrained in the language and griped about for possibly decades. Every language has a few issues that can be traced back to events like this.

eernstg commented 3 years ago

@CharlyZA-2 wrote:

thank you for engaging with the community

Thanks for the kind words!

@lmcdougald wrote:

This is an area that certainly warrants critique and scrutiny

Agreed, it is always important to try to seek good solutions, rather than ending up with mediocre solutions that just happened to occupy a good spot in the existing mental landscape.

I must admit that I tend to emphasize the structural software engineering consequences of a given design over the immediate syntactic appearance. It is also important to strive for a readable and convenient syntax for declaring/using any given feature, but I think the large scale structural consequences for the enclosing software must be given priority. In any case, a given structure can have lots of different syntactic forms, so we can strive for getting the large scale properties right first, and then fight about the syntactic details afterwards.

For example, the instance variable declaration int _x; differs from private int x; in that it forces each usage (that is, each call site for the getter and for the setter) to repeat the information that this is an access to a library-private instance member. Redundancy is rarely a benefit, but in this case the redundancy enables

So I tend to think that this particular syntax is a reasonable design choice for Dart. I haven't seen any proposals with similar properties where the access control is specified at the declaration alone (like private int x;).

That said, I must also admit that redundancy is bad (all other things equal), and _x is ugly. ;-)

lukemcdo commented 3 years ago

I think the private keyword should:

  1. also create an alias with a leading underscore, unless for some reason "private int _x" or something was done.
  2. if a global is imported and conflicts, assume this is deliberate and hide the local non-underscore version, leaving the underscore version only.

Effect: users that really want the private keyword can use it. I have nothing against the underscored version existing.

fabiocarneiro commented 3 years ago

@CharlyZA-2 wrote:

trust that all decisions you/Google make will be substantiated and for the benefit of the language

It impresses me that someone with a PHP background, a language that is so open and mature in terms of proposing and embracing new ideas from the community has this view of accepting anything as it is.

@eernstg Inspired by the PHP background comment above, I would suggest that a system of Request for comments is also introduced to Dart, in a similar style to what PHP does here https://wiki.php.net/rfc.

eernstg commented 3 years ago

I would suggest that a system of Request for comments is also introduced

We had a notion of a 'DEP' (Dart Evolution Proposal), e.g., https://github.com/dart-archive/dart_enhancement_proposals/issues/30. But we decided that the added formality and process wasn't contributing much value, and hence today's discussions take place in the language repo.

fabiocarneiro commented 3 years ago

@eernstg Creating a PDF that follows a template seems to be a bit cumbersome. I'm not surprised people weren't very happy about it.

The PHP system has a wiki-like page that after you get granted permissions, you can just press a button to create a new page and everything is done through the system. A more simple approach could be just creating a markdown file on a specific repo, and perhaps have a page that parses and displays it in a more beautiful way.

The main reason I am suggesting this is because of the voting system it provides. It democratizes the decision of what gets in and what doesn't. Rather than one or two maintainers participating in an issue, many relevant contributors can participate. Example of one that was rejected by the community https://wiki.php.net/rfc/match_expression

chornbe commented 3 years ago

Yes and no. Taking Flutter et al as the example here, I think the lack of a centralized driving force with actual defined goals is kind of the problem with it. Democratization sounds great, until the users want less abandonware, better documentation, more cohesive library development, less overlap and so forth.

If you’re going to die on a hill, the lunacy of the public/private declaration style isn’t the one to die on in the Flutter universe, IMO.

Moving 99% of the stuff available on pup.dev beyond v0.0.1 status would be a great start.

There’s too much shitty code and crappy, unfinished libraries gumming up the works.

realtalk

On Feb 9, 2021, at 9:57 AM, Fábio Carneiro notifications@github.com wrote:

@eernstg https://github.com/eernstg Creating a PDF that follows a template seems to be a bit cumbersome. I'm not surprised people weren't very happy about it.

The PHP system has a wiki-like page that after you get granted permissions, you can just press a button to create a new page and everything is done through the system. A more simple approach could be just creating a markdown file on a specific repo, and perhaps have a page that parses and displays it in a more beautiful way.

The main reason I am suggesting this is because of the voting system it provides. It democratizes the voting of what gets in and what doesn't get in the hands of many people, rather than one or two maintainers participating in an issue. Example of one that was rejected by the community https://wiki.php.net/rfc/match_expression https://wiki.php.net/rfc/match_expression — You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/dart-lang/sdk/issues/33383#issuecomment-776000380, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZHS6NCY325XRVBLEKJPZLS6FEL5ANCNFSM4FD23YCQ.

fabiocarneiro commented 3 years ago

@chornbe The suggestion was not to allow anyone to vote and I personally think it would be a big mistake. There needs to have some level of activity in the community and a deep understanding of the language and implications of your vote. The suggestion was more towards making it more transparent, traceable, and have a little more than one or two maintainers deciding on the language future. Let's say a group with the 30~50 most active Dart project maintainers?

Ing-Brayan-Martinez commented 3 years ago

Good morning, I am reading your comments in this productive debate and thought about responding to your comments as follows:

  1. I think that creating a forum where the community can propose and vote on the new features of language is the best idea I've heard, this is what the PHP community does with RFC, or Javascript with TC39, or OpenJDK with JEPs. This forum could be accessed from the official dart.dev website
  2. On the other hand I think that the reserved word private should be an alias _x to be able to have compatibility with previous versions and the existing library ecosystem
  3. And finally I communicate my willingness to participate in this group, forum, or what dart language development team decides to create, it would be an honor to be able to contribute to this wonderful community

Without more to say I bid you farewell, have an excellent day

eernstg commented 3 years ago

@fabiocarneiro wrote:

Creating a PDF that follows a template seems to be a bit cumbersome

That wasn't required, but the whole process was a bit more formalized. However, voting for a feature is done (in addition to adding comments) by clicking :+1: on the initial comment on the issue, and that is certainly already part of the discussions about the evolution of the language.

fabiocarneiro commented 3 years ago

That wasn't required, but the whole process was a bit more formalized. However, voting for a feature is done (in addition to adding comments) by clicking on the initial comment on the issue, and that is certainly already part of the discussions about the evolution of the language.

Right now then we have 26 votes in favor, 3 against, and 6 hearts. Would that be enough to assume the language should move in this direction?

Who voted for it? Which votes should be considered? What are the requirements to belong to this group? When and where does the voting take place? What if I remove or modify my reaction after the event takes place? What does it mean if I react with a :dancers: ? Is a tooltip a convenient way to inspect the results?

It is very different than this:

DeepinScreenshot_select-area_20210210130138

If something was rejected, perhaps an additional pool is useful to address the concerns in a future proposal:

  1. Not interested
  2. I don't want blocks
  3. Missing return values in blocks
  4. Missing pattern matching
  5. Missing explicit fallthrough
  6. BC break is not acceptable
  7. Wanted switch expressions instead
  8. Other

DeepinScreenshot_select-area_20210210130224

proshin-roman commented 3 years ago

Sorry, I don't know the actual status of this issue (still "closed"?), but I just came to Dart&Flutter universe. I have huge experience in Java, also started learning Swift that by itself looks very nice (I'm talking about the language only though). But I had to switch to Flutter just because I want to have multiplatform mobile applications without from the beginning. And then I faced this ugly solution with using _ symbol to mark private fields/methods. Sorry, but that's so ugly, it reminds me some bad PHP code and just shows that the language is not able to explicitly define intentions of developers (and that's already mention by a number of articles). I definitely would like to have an explicit private keyword - at least just as a replacement for _ symbol. The first argument for that (that lies on the surface) is that changing the visibility currently forces me to do renaming operation 🤦
So, I hope this feature will be considered at some point.

MatrixDev commented 3 years ago

also t would be great to have package access modifier... not everyone likes to work with files 50k lines each just to reduce visibility...

huylethanh commented 3 years ago

Dart should has the access modifier. a thing is uncomfortable is when I have a class, the variable is private "String _abc" and it is being called many places in the class, then i want to public that variable, i change it to String abc. i have to change that name in entier class. If we have the public and private keywork, we just change only one place. Please add access modifier. And the same request for method.