Skip to content

Commit f0ed9b7

Browse files
committed
Pass over scoped-caps
1 parent da87716 commit f0ed9b7

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

docs/_docs/reference/experimental/capture-checking/scoped-caps.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/capture-che
88

99
When discussing escape checking, we referred to a scoping discipline. That is, capture sets can contain only capabilities that are visible at the point where the set is defined. But that raises the question: where is a universal capability `cap` defined? In fact, what is written as the top type `cap` can mean different capabilities, depending on scope. Usually a `cap` refers to a universal capability defined in the scope where the `cap` appears.
1010

11-
A useful mental model is to think of `cap` as a "container" that can _absorb_ concrete capabilities. When you write `T^` (shorthand for `T^{cap}`), you're saying "this value may capture some capabilities that will flow into this `cap`." Different `cap` instances in different scopes are different containers: a capability that flows into one doesn't automatically flow into another.
11+
A useful mental model is to think of `cap` as a "container" that can _absorb_ concrete capabilities. When you write `T^` (shorthand for `T^{cap}`), you're saying "this value may capture some capabilities that will flow into this `cap`." Different `cap` instances in different scopes are different containers: a capability that flows into one doesn't automatically flow into another. We will further expand on this idea later when discussing [separation checking](separation-checking.md).
1212

1313
### Existential Binding
1414

@@ -44,7 +44,7 @@ is interpreted as having an existentially bound `cap` in the result, like this:
4444
```
4545
The same rules hold for the other kinds of function arrows, `=>`, `?->`, and `?=>`. So `cap` can in this case absorb the function parameter `x` since `x` is locally bound in the function result.
4646

47-
However, the expansion of `cap` into an existentially bound variable only applies to functions that use the dependent function style syntax, with explicitly named parameters. Parametric functions such as `A => B^` or `(A₁, ..., Aₖ) -> B^` don't bind their result cap in an existential quantifier. For instance, the function
47+
However, the expansion of `cap` into an existentially bound variable only applies to functions that use the dependent function style syntax, with explicitly named parameters. Parametric functions such as `A => B^` or `(A₁, ..., Aₖ) -> B^` don't bind the `cap` in their return types in an existential quantifier. For instance, the function
4848
```scala
4949
(x: A) -> B -> C^
5050
```
@@ -74,8 +74,8 @@ To summarize:
7474

7575
## Levels and Escape Prevention
7676

77-
Each capability has a _level_ corresponding to where it was defined. The level determines where a capability can flow: it can flow into `cap`s at the same level or more deeply nested, but not outward to enclosing scopes. Later sections on [capability classifiers](classifiers.md) will add a controlled
78-
escape mechanism.
77+
Each capability has a _level_ corresponding to where it was defined. The level determines where a capability can flow: it can flow into `cap`s at the same level or more deeply nested, but not outward to enclosing scopes (which would mean a capability lives longer than its lexical lifetime). Later sections on [capability classifiers](classifiers.md) will add a controlled mechanism that permits escaping/flowing outward for situations
78+
where this would be desirable.
7979

8080
### How Levels Are Computed
8181

@@ -153,7 +153,7 @@ called _charging_ the capability to the environment.
153153
```scala
154154
def outer(fs: FileSystem^): Unit =
155155
def inner(): () ->{fs} Unit =
156-
() => fs.read() // cap1 is used here
156+
() => fs.read() // fs is used here
157157
inner()
158158
```
159159

@@ -173,10 +173,10 @@ The closure is declared pure (`() -> Unit`), meaning its `cap` is the empty set.
173173

174174
## Visibility and Widening
175175

176-
When capabilities flow outward to enclosing scopes, they must remain visible. A local capability cannot appear in a type outside its defining scope. In such cases, the capture set is _widened_ to the smallest visible superset:
176+
When capabilities flow outward to enclosing scopes, they must remain visible. A local capability cannot appear in a type outside its defining scope. In such cases, the capture set is _widened_ to the smallest visible super capture set:
177177

178178
```scala
179-
def test(fs: FileSystem^): Logger^{cap} =
179+
def test(fs: FileSystem^): Logger^{fs} =
180180
val localLogger = Logger(fs)
181181
localLogger // Type widens from Logger^{localLogger} to Logger^{fs}
182182
```

0 commit comments

Comments
 (0)