-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Decompose Mutable #24495
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
base: main
Are you sure you want to change the base?
Decompose Mutable #24495
Conversation
docs/_docs/reference/experimental/capture-checking/mutability.md
Outdated
Show resolved
Hide resolved
docs/_docs/reference/experimental/capture-checking/mutability.md
Outdated
Show resolved
Hide resolved
| r | ||
| ``` | ||
| Here, `r` is a fresh reference of type `Ref[String]` that escapes the scope of `withFile`. That's OK only since | ||
| `Ref` is classified as `Unscoped`. Since `Unscoped` is a [classifier](./classifiers.md) it means that `Ref` cannot possibly capture `f`, which as a `File` is not classified as `Unscoped`. So returning a `Ref` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a scoped capability capture an unscoped capability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the Ref need to be fresh to be allowed to be captured by the value returned from op?
For example, suppose we changed the signature of withFile to:
def withFile[T](op: (f: File^, r: Ref[String]^) => T): T =Could we then call it with an op whose result type captures r?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now, no, but this might be an implementation restriction. The unscoped nature of Unscoped caps works only in covariant toplevel positions.
docs/_docs/reference/experimental/capture-checking/mutability.md
Outdated
Show resolved
Hide resolved
docs/_docs/reference/experimental/capture-checking/mutability.md
Outdated
Show resolved
Hide resolved
Also: drop redundant statement in captureSetImpliedByFields
Still missing: Make Mutable an Unscoped
Fix: the APPLY rule had to be changed so that it does not kick in if the result has Unscoped capabilities. These need to be preserved, we cannot approximate by the (possibly pure) function type.
Caught one bug in CaptureSet
|
|
||
| `update` can also be used on an inner class of a class or object extending `Mutable`. It gives all code in the class the right | ||
| to access exclusive capabilities in the class environment. Normal classes | ||
| `update` can also be used on an inner class of a class or object extending `Stateful`. It gives all code in the class the right to access exclusive capabilities in the class environment. Normal classes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| `update` can also be used on an inner class of a class or object extending `Stateful`. It gives all code in the class the right to access exclusive capabilities in the class environment. Normal classes | |
| `update` can also be used on an inner class of a class or object extending `Stateful`. It gives all code in the inner class the right to access exclusive capabilities in the outer class' environment. Normal classes |
It's otherwise ambiguously worded. Is my understanding correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: "normal" classes. Are those non-Stateful classes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And are such inner update classes implicitly also Stateful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. In fact, we need to re-evaluate update for inner classes. Maybe update should go on the constructor.
| An update method cannot implement or override a normal method, whereas normal methods may implement or override update methods. Since methods such as `toString` or `==` inherited from Object are normal methods, it follows that none of these methods may be implemented as an update method. | ||
|
|
||
| The `apply` method of a function type is also a normal method, hence `Mutable` classes may not implement a function type using an update method as the `apply` method. | ||
| The `apply` method of a function type is also a normal method, hence `Stateful` classes may not implement a function type using an update method as the `apply` method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we can write lambdas that manipulate stateful caps, but function types aren't Stateful and their apply isn't update,
I'm still somewhat missing a clear guideline when programmers should use Stateful and when not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a paragraph at the end of the Iterator discussion that goes into that. Maybe put a forward reference here, or move the paragraph up.
First commit: New doc page for decomposed mutables
Todo: