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

Support restriction of access to this object #757

Open
eernstg opened this issue Dec 20, 2019 · 0 comments
Open

Support restriction of access to this object #757

eernstg opened this issue Dec 20, 2019 · 0 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@eernstg
Copy link
Member

eernstg commented Dec 20, 2019

This issue is a proposal that we add support for marking instance members as this protected (alternatively: protected) to indicate that they can only be accessed on the current object (as in this.myMember or, if this is added implicitly: myMember).

Given that we may well add support for sound variance (starting with declaration site variance), the ability to constrain access to instance members to the enclosing object only gains new urgency.

A typical example would be that an immutable data structure naturally lends itself to sound covariance. However, an implementation may well wish to cache some values for performance reasons, and that cannot be done in a type safe manner with the sound discipline that is applied to member signatures where a soundly covariant type variable is used. Similarly, an implementation may well benefit from the ability to express sub-computations as instance methods, and they cannot accept arguments whose type is a soundly covariant type variable.

For example:

class Link<out X extends num> {
  final X x;
  final Link<X>? next;
  Link(this.x, this.next);
  X? _max; // Error!
  X get max {
    X? result = _max;
    if (result != null) return result;
    result = next?.max;
    return result != null
        ? (_max = result >= x ? result : x)
        : (_max = x);
  }
}

The example above would give rise to a compile-time error at the comment, because the mutable instance variable _max induces a setter whose parameter type is X?, which is not allowed when X is out. In general, this kind of restriction is required in order to maintain the soundness properties that are the whole point of having explicit variance control in the first place.

However, there is no soundness issue for code in a scope where the type variable X is in scope, which means that there is no soundness issue in having an instance variable like _max as long as it is only accessed on this. (It is not sufficient that the receiver is some other object of type Link<X>, because that other object could, by covariance, have an actual value for X which is different from the one of the current object).

We could use the keyword sequence this protected in order to express the property that a given instance member can only be accessed on this. We could also use a plain protected, if we don't insist on reserving that keyword for the standard meaning (where it is allowed to access the feature on any object with the enclosing type, not just this). We could then make the example work as follows:

class Link<out X extends num> {
  final X x;
  final Link<X>? next;
  Link(this.x, this.next);
  this protected X? _max;
  X get max {
    X? result = _max;
    if (result != null) return result;
    result = next?.max;
    return result != null
        ? (_max = result >= x ? result : x)
        : (_max = x);
  }
}
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

1 participant