0
# Capability System
1
2
Experimental capture checking system for capability-safe programming, providing fine-grained control over side effects and resource access.
3
4
## Capabilities
5
6
### Core Capability Types
7
8
Foundation types for the capability system.
9
10
```scala { .api }
11
/**
12
* Base trait for all capability classes
13
* Capabilities represent permissions or resources that can be captured
14
*/
15
trait Capability extends Any
16
17
/**
18
* Universal capture reference representing all capabilities
19
* Used in function signatures to indicate capture of all capabilities
20
*/
21
object cap extends Capability
22
23
/**
24
* Carrier trait for capture set type parameters
25
* Used internally for representing sets of captured capabilities
26
*/
27
trait CapSet extends Any
28
29
/**
30
* Constraint that capture set C contains capability R
31
* Used in type signatures to express capture requirements
32
*/
33
sealed trait Contains[+C, R]
34
35
/**
36
* Existential capability types for abstraction over unknown capabilities
37
*/
38
sealed trait Exists extends Capability
39
```
40
41
**Usage Examples:**
42
43
```scala
44
import scala.caps.*
45
46
// Function that requires no capabilities
47
def pureFunction(x: Int): Int = x * 2
48
49
// Function that captures the universal capability
50
def impureFunction(): Unit = {
51
println("Side effect!") // Requires cap capability
52
}
53
54
// Function with explicit capability parameter
55
def withCapability[C <: Capability](f: C => Unit)(using c: C): Unit = f(c)
56
57
// Using capability constraints
58
def constrainedFunction[C](using Contains[C, java.io.FileSystem]): Unit = {
59
// Can perform file operations
60
}
61
```
62
63
### Exception Capabilities
64
65
Capability system for exception handling.
66
67
```scala { .api }
68
/**
69
* Capability for throwing exceptions of type E
70
* Erased at runtime - only provides compile-time tracking
71
*/
72
erased class CanThrow[-E <: Exception] extends Capability
73
74
object CanThrow:
75
/** Unsafe capability that can throw any exception */
76
object unsafeExceptions:
77
given canThrowAny: CanThrow[Exception] = ???
78
```
79
80
**Usage Examples:**
81
82
```scala
83
import scala.caps.CanThrow
84
85
// Function that can throw IOException
86
def readFile(path: String)(using CanThrow[java.io.IOException]): String = {
87
// File reading implementation that might throw IOException
88
scala.io.Source.fromFile(path).mkString
89
}
90
91
// Function that handles the capability
92
def safeReadFile(path: String): Either[Exception, String] = {
93
try {
94
given CanThrow[java.io.IOException] = CanThrow.unsafeExceptions.canThrowAny
95
Right(readFile(path))
96
} catch {
97
case e: Exception => Left(e)
98
}
99
}
100
101
// Multiple exception types
102
def riskyOperation()(using CanThrow[IllegalArgumentException], CanThrow[java.io.IOException]): Unit = {
103
if (scala.util.Random.nextBoolean())
104
throw new IllegalArgumentException("Random failure")
105
else
106
throw new java.io.IOException("IO failure")
107
}
108
```
109
110
### Reach Capabilities
111
112
Annotations for expressing reachability of capabilities.
113
114
```scala { .api }
115
/**
116
* Annotation for marking reach capabilities
117
* Used to express that a capability can be reached through method calls
118
*/
119
final class use extends annotation.StaticAnnotation
120
```
121
122
**Usage Examples:**
123
124
```scala
125
import scala.caps.use
126
127
// Method that reaches a capability through its parameter
128
def processWithReach(@use resource: FileReader): String = {
129
resource.read() // The capability is "reached" through the parameter
130
}
131
132
// Class with reach capability annotation
133
class Service(@use connection: DatabaseConnection) {
134
def query(sql: String): ResultSet = connection.execute(sql)
135
}
136
```
137
138
### Unsafe Operations
139
140
Escape hatches for capability system constraints.
141
142
```scala { .api }
143
/**
144
* Mark constructor parameters as untracked by the capture checker
145
*/
146
object untrackedCaptures
147
148
/**
149
* Remove all capture sets from a value's type
150
* Use with extreme caution - bypasses capability safety
151
*/
152
def unsafeAssumePure[T](x: T): T = x
153
154
/**
155
* Suppress separation checks for the given operation
156
* Allows potentially unsafe capability mixing
157
*/
158
def unsafeAssumeSeparate(op: Any): op.type = op
159
```
160
161
**Usage Examples:**
162
163
```scala
164
import scala.caps.unsafe.*
165
166
// Remove capture tracking (unsafe)
167
def makePure[T](impureValue: T): T = {
168
unsafeAssumePure(impureValue) // Now treated as pure
169
}
170
171
// Bypass separation checks
172
def mixCapabilities(cap1: SomeCapability, cap2: AnotherCapability): Unit = {
173
unsafeAssumeSeparate {
174
// Operations that would normally violate separation
175
cap1.operation()
176
cap2.operation()
177
}
178
}
179
180
// Constructor with untracked parameters
181
class UnsafeService(connection: DatabaseConnection) extends untrackedCapabilities:
182
// connection is not tracked by capture checker
183
def query(sql: String) = connection.execute(sql)
184
```
185
186
### Internal Capability Support
187
188
Internal utilities for capability system implementation.
189
190
```scala { .api }
191
/**
192
* Wrapper for capture argument lists
193
* Used internally by the compiler for capability inference
194
*/
195
def capsOf[CS]: Any = ???
196
197
extension (x: Any)
198
/**
199
* Reach capability encoding for internal use
200
* Expresses that x reaches some capability
201
*/
202
def reachCapability: x.type = x
203
```
204
205
**Usage Examples:**
206
207
```scala
208
import scala.caps.internal.*
209
210
// Internal use - typically handled by compiler
211
def internalCapabilityProcessing[CS](): Unit = {
212
val caps = capsOf[CS]
213
// Internal capability manipulation
214
}
215
216
// Reach capability extension (compiler-generated)
217
def someMethod(resource: FileHandle): Unit = {
218
val reachable = resource.reachCapability
219
// Express that resource's capabilities are reachable
220
}
221
```
222
223
### Practical Capability Patterns
224
225
Common patterns for using capabilities in real applications.
226
227
```scala { .api }
228
// Resource management pattern
229
trait Resource extends Capability:
230
def close(): Unit
231
232
class FileResource(path: String) extends Resource:
233
def read(): String = ???
234
def close(): Unit = ???
235
236
def withResource[T, R <: Resource](resource: R)(f: R => T): T = {
237
try f(resource)
238
finally resource.close()
239
}
240
241
// IO capability pattern
242
trait IO extends Capability
243
244
object IO:
245
given globalIO: IO = new IO {}
246
247
def println(s: String)(using IO): Unit = {
248
scala.Predef.println(s) // Requires IO capability
249
}
250
251
// Network capability pattern
252
trait Network extends Capability
253
254
class HttpClient(using Network):
255
def get(url: String): String = ???
256
def post(url: String, data: String): String = ???
257
258
// Database capability pattern
259
trait Database extends Capability:
260
def query(sql: String): List[Map[String, Any]]
261
def execute(sql: String): Int
262
263
class Repository(using db: Database):
264
def findUser(id: Int): Option[User] = {
265
val results = db.query(s"SELECT * FROM users WHERE id = $id")
266
results.headOption.map(User.fromMap)
267
}
268
```
269
270
**Usage Examples:**
271
272
```scala
273
// Resource management
274
val result = withResource(FileResource("data.txt")) { file =>
275
file.read()
276
}
277
278
// IO operations
279
given IO = IO.globalIO
280
println("Hello, capabilities!") // Requires IO capability
281
282
// Network operations
283
given Network = new Network {}
284
val client = HttpClient()
285
val response = client.get("https://api.example.com/data")
286
287
// Database operations
288
given Database = new Database {
289
def query(sql: String) = List(Map("id" -> 1, "name" -> "Alice"))
290
def execute(sql: String) = 1
291
}
292
293
val repo = Repository()
294
val user = repo.findUser(1)
295
```
296
297
## Types
298
299
```scala { .api }
300
// Core capability types
301
trait Capability extends Any
302
object cap extends Capability
303
trait CapSet extends Any
304
sealed trait Contains[+C, R]
305
sealed trait Exists extends Capability
306
307
// Exception capabilities
308
erased class CanThrow[-E <: Exception] extends Capability
309
310
// Annotations
311
final class use extends annotation.StaticAnnotation
312
313
// Unsafe operations
314
object untrackedCaptures
315
def unsafeAssumePure[T](x: T): T
316
def unsafeAssumeSeparate(op: Any): op.type
317
318
// Internal support
319
def capsOf[CS]: Any
320
extension (x: Any) def reachCapability: x.type
321
```