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.3k stars 1.59k 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());
}
CostachescuCristinel commented 3 years ago

You guys are making this a longer discussion than it needs to be. This could have been ended quite sooner if the request was made and undestood by everyone like this:

Implement a keyword private that annotates identifiers as being library private - effectively doing the same work that (underscore) does now._

Basically, what most people were looking for was to be able to write this:

class Example {
    private int foo = 5;
    ...
}

instead of:

class Example {
    int _foo = 5;
    ...
}

No need for a public keyword, any identifiers not marked with private would be public by default - as it is current behavior. Introducing this does not require any additional dynamic checks that were discussed at the beginning of the discussion, nor behavior changes in the Dart core. In fact, the behavior would be the same with the added benefit of improved code readability.

You might argue that you would have to clarify in the docs that the private keyword in Dart does not mean the same thing as it does in other languages. Right... imagine having to explain in your docs that, not only Dart has private identifiers, but that they are only private to the library, not to the class defining them; and it also uses an underscore-prefixed identifier to mark such private identifiers. Yup, you got yourselves fooled, twice.

This discussion reminds me of JavaScript's private class fields proposal, equally long and unnecessary, and they still chose the worst option.

Anyway, just my 0.02$...

MatrixDev commented 3 years ago

@CostachescuCristinel there are a lot of comments to add package, protected etc.

chornbe commented 3 years ago

I didn’t say it wasn’t a worthy pursuit; the underscore is flat out stupid in terms of productive flow of typing - before getting into the idiocy of it being unlike any other language.

I’m just saying if you’re going to pick one thing as your ‘must have’, there are way bigger fish to fry than the idiotic underscore.

$.02

On Apr 13, 2021, at 11:42 AM, Rostyslav Lesovyi @.***> wrote:

@CostachescuCristinel https://github.com/CostachescuCristinel there are a lot of comments to add package, protected etc.

— 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-818838227, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZHS6NDSBWSBYLBU6O3MDLTIRRADANCNFSM4FD23YCQ.

CostachescuCristinel commented 3 years ago

@MatrixDev I would agree with them on looking after such language features, for good OOP reasons I'd add. But this could be a topic for another discussion. As far as I can see, the initial requests were only about getting rid of that underscore notation in favor of an explicit private keyword (with public thrown in the mix for completeness I guess, but could've been disregarded as well).

Anyway, I'm not going to make this discussion any longer. I ended up here from the Dart language tour, and I was just amazed by the lengthy discussion. My best regards and good luck to you all :)

PapaNappa commented 3 years ago

From what I can see, there are two major points in favour of the _ as opposed to a private modifier:

But having a look at the "greater structure", I feel there are higher priority points that favour a private modifier. (I get that this is very late in the development of Dart and things likely don’t change, but I think it’s still a valuable discussion.)

What are the benefits of having dynamic calls in productive code or for productive coding? In my experience, a sloppy coding style to "just test something out" leads very quickly to a worse coding productivity and less robust, maintainable code. What are the use cases for "especially dynamic" code? I think the benefits of true static type checking outweigh the benefits of dynamic typing.

In a similar manner, what are the benefits of allowing overriding private members? Most languages don’t allow this (or mark them using the protected keyword, not some marker), and even if allowed, the rare use cases could justify a small performance hit. Is this really such an important feature that it warrants such inconsistent and unusual approach?

Again, looking at the greater structure, having a property of a field encoded in the name is a bit obscure. Having _ for one single purpose is inconsistent with the rest. From the perspective of robust and clean, maintainable code, following "best practices" of similar languages seems more important than specialty features such as private member overriding.

From Dart’s overview page:

The Dart language is type safe; it uses static type checking to ensure that a variable’s value always matches the variable’s static type. Sometimes, this is referred to as sound typing. Although types are mandatory, type annotations are optional because of type inference. The Dart typing system is also flexible, allowing the use of a dynamic type combined with runtime checks, which can be useful during experimentation or for code that needs to be especially dynamic.

This also seems a bit contradictory. What is Dart, statically typed or dynamically typed? Can you reasonably have both?

If Dart prefers to be dynamically typed, and values highly-efficient private member overriding over de-facto standards from other languages, so be it. But advertising "sound null-safety" and "static typing" where the type "always" matches might be misleading, resulting in such discussions.

MatrixDev commented 3 years ago

@scbabacus-midnight you can't compare Kotlin multi-platform with Dart. Dart is mostly used in combination with Flutter. Kotlin at this moment doesn't have even a fraction of platform-specific functionality nor libraries as Flutter does.

As I suggested previously Dart can have both - static and dynamic typing (adding private/protected/public without removing _). so you can write both ways:

PS: this argument can go the other way as well - you're not the only one, a lot of people would love to have proper static typing.

midnight-wonderer commented 3 years ago

@MatrixDev Thank you for @ me. I just realized I used a work account to express opinions. Let me switch to my account. (Sorry for the noise everyone on the list) As PapaNappa mentioned, there is no point in discussing what to do now, not gonna happen. I just respond to the called for dynamic typing use cases.

Original post:

FWIW I prefer dynamic typing; different people solving different problems. I would disagree with a lot of things in Dart but understand that they are solving their problems.

For me, "dynamic typing" can also mean "interface everywhere".
If someone else implements something that accepts dynamic-typed parameters, I can always implement another object with the same signature they expected without modifying other people's classes to declare an interface. And those interfaces will be possible everywhere, even unintentional. And that's how the Ruby community works together while still agnostic to other people's code. (I know, in Dart, a class can implement another class; that's weird, btw)

So no, not everyone is on the static-typing camp. And just because you cannot be productive in a dynamic-typing environment doesn't mean everyone does.

From what I observed, Dart is a machine-oriented language. The people behind Dart care deeply about performance and optimization. They design the language, so it is easy to optimize. (take const keyword as an instance, and they are openly doing it all over the place) Average people don't even have to care about the performance that much.

The Dart team will favor machines; there is nothing we can change about that; they are in their game and are good at it. After hearing their reasoning, I will accept Dart the way it is. For people who prefer human-oriented language with static typing, I would recommend Kotlin. The language can build on many platforms now, even web apps; it is somewhat similar to Dart IMHO.

pulstar commented 3 years ago

@huylethanh

then i want to public that variable, i change it to String abc. i have to change that name in entire class. If we have the public and private keywork, we just change only one place.

In Android Studio and IntelliJ, just place the cursor over the variable name, where it is declared and type SHIFT + F6. You can also use this tool to rename methods and classes too. It will rename in the whole project.

MatrixDev commented 3 years ago

In Android Studio and IntelliJ, just place the cursor over the variable name, where it is declared and type SHIFT + F6. You can also use this tool to rename methods and classes too. It will rename in the whole project.

And you'll have huge diff in the commit if variable is used in multiple files. Also this might lead to merge conflicts.

huylethanh commented 3 years ago

@huylethanh

then i want to public that variable, i change it to String abc. i have to change that name in entire class. If we have the public and private keywork, we just change only one place.

In Android Studio and IntelliJ, just place the cursor over the variable name, where it is declared and type SHIFT + F6. You can also use this tool to rename methods and classes too. It will rename in the whole project.

Yeah. I know that, but i meant we would change a lot of line. And when we commit the file. It's so hard for review the code changed.

pulstar commented 3 years ago

@huylethanh

Yeah. I know that, but i meant we would change a lot of line. And when we commit the file. It's so hard for review the code changed.

I agree. The PRIVATE keyword would be better.

CharlVS commented 2 years ago

Why is this issue still open? This isn't the right place for debates and subjective opinions. This issue can't be "solved".

On Wed, Dec 8, 2021 at 1:10 PM cedvdb @.***> wrote:

Interesting that nobody has been able to give any concrete example as to what problem class privacy would solve

Let's flip it around, I've not seen many use cases where _member is accessed from another class in the same file.

Like this:

class Test { final int _priv = 3; }

class Also { Also() { print(Test()._priv); } }

There are some use cases for public APIs, other languages have it too, like Java default access modifiers, where values can be accessed only within the same folder. The issue is that to have this feature, you have to put the classes in the same file, which is really intrusive. I find codebases where class are not separated into files harder to navigate, to each his own I guess.

Also features like this https://github.com/dart-lang/language/issues/2005 have some inconsistencies built into it because of the _.

— 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-988717830, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASS4QSH7BR4R7BMUYYNSM3TUP44JVANCNFSM4FD23YCQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

MatrixDev commented 2 years ago

@CharlyZA-2, is it still open? Also this is the only place people can realistically debate and give their subjective opinions.

cedvdb commented 2 years ago

There are objectives arguments to be made why access modifiers that give finer control, like "package private" (java) can make for better public api of "package". It is quite frustrating that the only way to have that is to put everything in the same file.

However I hope there is going to be some sort of module where the folders inside that module can access properties of said module while folders outside of the module cannot. Similar to what library is today but extended to multiple file without needing to use part.

zoechi commented 2 years ago

@cedvdb use "part" and "part of"

msisinni commented 1 year ago

If encapsulation keywords would be too much of a pain to implement, why not add more encapsulation symbols for variable names for the language? Already, we have nothing=public, _=file-protected. For example, add in ~=private and \=protected (or whatever acceptable symbols you want). Edit: or replace the idea of adding private with adding an equivalent to package-protected, since files in Dart are handled differently than they are in Java.

Sure, it's confusing as hell, but Dart's use of underscore for file-protected is already unintuitive.

cedvdb commented 1 year ago

I wouldn't say it's unintuitive as it's been a convention in various languages. Maybe those symbols would be a problem on some keyboards too.

What I'd like is to make everything "internal" when there is no "public" access modifier in front and add a private keyword with the obligation to use "_". The internal change can be handled by dart fix. That plus some sort of module that doesn't require a full fledged package, it's too slow and bloated currently.

EG:

  /a (module)
    /b (module)
       /c
    /d (module)
pulstar commented 1 year ago

I can hardly imagine what Flutter development would be like today if Google had opted for Python instead of pushing their own programming language. Python is by far the most popular language right now: https://www.youtube.com/watch?v=qQXXI5QFUfw

robsenshemsedin commented 1 year ago

Dart has easy to write syntax, one of the reasons for that is the use of _ as access modifier.

olek93 commented 10 months ago

I am just learning Dart right now and reading through official docs, I have got here. I see many developers (especially Java and such lang related ones) complain about not having private, protected access modifiers... Think about the most popular language right now... wait its Python that has _ characters indicating that something should not be used, whereas it does not enforce privacy of anything.

Think about AI today and what it is developed in? Why?

Why do people want to use Python? Maybe because even though they write more expensive in work dynamic code, they achieve the same goals or outstanding goals (like implementing AI) using less concepts?

Think about who Dart language should be attractive to today - Java devs, C# devs or Python devs? Taking attention of the most robust python community seems more like goal nowadays, than giving comfort to all those super smart heads implementing hexagonal architectures that only they and few of they colleagues fully understand and can use efficiently. Over complication of mature OOP only langages makes them die actually (Believe me, when I started to learn C# and stumbled upon private, protected and public as a starting junior, adding all OOP class-related complexity, I dumped it. As a lot of people probably did).

Stop crying about having to use python-like _ because future of coding is LESS CONCEPTS, more perfect and easy code DESIGN. For me flutter tries to blend a language that resembles a bit of typescript, C# and python and I feel its a good direction. Think about why Python wins in AI, backend most secure development (Django and Django REST Framework). All that works WITHOUT private and protected anywhere!

MatrixDev commented 10 months ago

I am just learning Dart right now and reading through official docs, I have got here. I see many developers (especially Java and such lang related ones) complain about not having private, protected access modifiers... Think about the most popular language right now... wait its Python that has _ characters indicating that something should not be used, whereas it does not enforce privacy of anything.

Think about AI today and what it is developed in? Why?

Why do people want to use Python? Maybe because even though they write more expensive in work dynamic code, they achieve the same goals or outstanding goals (like implementing AI) using less concepts?

Think about who Dart language should be attractive to today - Java devs, C# devs or Python devs? Taking attention of the most robust python community seems more like goal nowadays, than giving comfort to all those super smart heads implementing hexagonal architectures that only they and few of they colleagues fully understand and can use efficiently. Over complication of mature OOP only langages makes them die actually (Believe me, when I started to learn C# and stumbled upon private, protected and public as a starting junior, adding all OOP class-related complexity, I dumped it. As a lot of people probably did).

Stop crying about having to use python-like _ because future of coding is LESS CONCEPTS, more perfect and easy code DESIGN. For me flutter tries to blend a language that resembles a bit of typescript, C# and python and I feel its a good direction. Think about why Python wins in AI, backend most secure development (Django and Django REST Framework). All that works WITHOUT private and protected anywhere!

If everything was so nice flutter team wouldn't introduce ugly workaround in the form of @protected.

pulstar commented 5 months ago

I see that no one liked my comment above. I understand and accept this. In fact, Flutter's biggest problem isn't the language. Dart is an excellent language and I'm surprised it isn't adopted as much as others. The biggest problem I've found with the Flutter framework is the constant breaking of backwards compatibility and the hell of dependencies between libraries that this entails. With each new version it is necessary to rewrite a lot of code and test everything again. What is the advantage of having a single code base if it is always changing? I've been away from Flutter development for some time because of this. I hope this has improved and that new versions mature the standards, as it is a fantastic framework.

MUzayr commented 2 months ago

Dart team need to concentrate more on the current problems facing by JAVA / C# /TYPESCRIPT coders.