Skip to content

Conversation

@odersky
Copy link
Contributor

@odersky odersky commented Nov 20, 2025

First commit: New doc page for decomposed mutables

Todo:

  • discuss the design
  • implementation

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`
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

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.
@odersky odersky requested a review from a team as a code owner November 21, 2025 18:09

`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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`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?

Copy link
Contributor

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?

Copy link
Contributor

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?

Copy link
Contributor Author

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.
Copy link
Contributor

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.

Copy link
Contributor

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.

@bracevac bracevac changed the title Decopose Mutable Decompose Mutable Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants