Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add private set property modifier #4206

Open
tilucasoli opened this issue Dec 13, 2024 · 3 comments
Open

Add private set property modifier #4206

tilucasoli opened this issue Dec 13, 2024 · 3 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@tilucasoli
Copy link

tilucasoli commented Dec 13, 2024

Introduce a property-level modifier similar to Swift’s private(set) functionality. This would allow a class to expose a property for reading externally while restricting write access.

Motivation

In Swift, a common pattern is to declare properties as public private(set), which makes them publicly readable but only privately (or internally) writable. However, Dart does not have a similar feature, so we have to create a private variable along with a getter to achieve the same functionality.

Swift Example:

public class SomeClass {
    public private(set) var count: Int = 0
    
    public func increment() {
        count += 1
    }
}

Dart Example:

class SomeClass {
  int _count = 0;
  
  int get count => _count;
  
  void increment() {
    _count++;
  }
}

Proposed Solution

_set

class SomeClass {
  // Publicly readable, privately writable
   _set int count = 0;

  void increment() {
    count += 1; // Allowed
  }
}

// Outside SomeClass
void main() {
  final obj = SomeClass();
  print(obj.count); // Allowed
  // obj.count = 5; // Not allowed: write access is private
}

@nonVisibleSet

Alternatively, a annotation-based could be another option.

class SomeClass {
  @nonVisibleSet
  int count = 0; // read from anywhere, write only from within this class
}
@tilucasoli tilucasoli added the feature Proposed language feature that solves one or more problems label Dec 13, 2024
@lrhn
Copy link
Member

lrhn commented Dec 13, 2024

I've suggested something like that before. Can't find it right now.
The idea was to have bundled "property" declarations where you could declare implicit getter and/or setter for a variable independently, and also choose their names.

Strawman syntax:

int _value {
  get value;
  set;
};

This block states that there is a getter named value and a setter named _value for a variable which is itself named _value.(The name of a variable can only be used in one place: Constructor initialization, as this._value or _value = expr. Any other reference to the variable is a reference to a getter or setter, but initialization refers to the underlying storage location itself.)

By allowing you to specify an alternative name for a getter or setter, you can end up with default getters and setters for a variable with different names, including one being private.

Another way to write the same thing might be

int value { set _value; };

because you can't omit a getter, so omitting it is equivalent to get;, which is short for get value;.
You only need to say whether there is a setter, and then you can give it a non-standard name.

(Annotations are not an option. An annotation cannot change language behavior, so @nonVisibleSet int count = 0; would be visible to the language. The analyzer may warn if you access it, but you can // ignore: that if you want to.)

@tilucasoli
Copy link
Author

I like this sintax, for me it works

int a { set _a; }

What if I set an initial value for 'a'?

It would be something like this?

int a = 1 { set _a; }

@tatumizer
Copy link

For each verb in {get, set}, there are 4 possibilities:

  • omit it
  • write only verb
  • write verb followed by a _name (with the underscore)
  • write verb followed by a name (with no underscore)

Each of those has to be translated into the human language while reading the program (16 combinations in total).
That's not all. The declared name also comes in 2 colors: int _a and int a, so this has to be taken into account while figuring out the overall meaning.
It's complicated 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants