dart-lang / dart-lang/language

Support restriction of access to `this` object

Open
#757 0 comments 4 reactions 0 assignees View on GitHub
feature
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

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](https://github.com/dart-lang/language/issues/524)), 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:

```dart
class Link {
final X x;
final Link? 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`, 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:

```dart
class Link {
final X x;
final Link? 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);
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.