You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/docs/reference/experimental/canthrow.md
+5-5Lines changed: 5 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -117,7 +117,7 @@ a function `f` like this:
117
117
vallimit=10e9
118
118
classLimitExceededextendsException
119
119
deff(x: Double):Double=
120
-
if x < limit thenf(x) elsethrowLimitExceeded())
120
+
if x < limit thenx * x elsethrowLimitExceeded()
121
121
```
122
122
You'll get this error message:
123
123
```
@@ -136,7 +136,7 @@ You'll get this error message:
136
136
As the error message implies, you have to declare that `f` needs the ability to throw a `LimitExceeded` exception. The most concise way to do so is to add a `canThrow` clause:
137
137
```scala
138
138
deff(x: Double):Double canThrow LimitExceeded=
139
-
if x < limit thenf(x) elsethrowLimitExceeded())
139
+
if x < limit thenx * x elsethrowLimitExceeded()
140
140
```
141
141
Now put a call to `f` in a `try` that catches `LimitExceeded`:
142
142
```scala
@@ -192,7 +192,7 @@ To summarize, the extension for safer exception checking consists of the followi
192
192
- It augments the type checking of `throw` by _demanding_ a `CanThrow` ability or the thrown exception.
193
193
- It augments the type checking of `try` by _providing_`CanThrow` abilities for every caught exception.
194
194
195
-
That's all. It's quite noteable that one can do exception checking in this way without any special additions to the type system. We just need regular givens and context functions. Any runtime overhead is eliminated using `erased`.
195
+
That's all. It's quite remarkable that one can do exception checking in this way without any special additions to the type system. We just need regular givens and context functions. Any runtime overhead is eliminated using `erased`.
196
196
197
197
## Caveats
198
198
@@ -218,7 +218,7 @@ With the system presented here, this function typechecks, with expansion
218
218
defescaped(xs: Double*): () =>Int=
219
219
try
220
220
givenctl:CanThrow[LimitExceeded] =???
221
-
() => xs.map(f(using ctl)).sum
221
+
() => xs.map(x => f(x)(using ctl)).sum
222
222
catchcaseex: LimitExceeded=>-1
223
223
```
224
224
But if you try to call `escaped` like this
@@ -237,5 +237,5 @@ And it would have many other applications besides: Exceptions are a special case
237
237
238
238
But even without these additional mechanisms, exception checking is already useful as it is. It gives a clear path forward to make code that uses exceptions safer, better documented, and easier to refactor. The only loophole arises for scoped abilities - here we have to verify manually that these abilities do not escape. Specifically, a `try` always has to be placed in the same computation stage as the throws that it enables.
239
239
240
-
Put another way: If the status quo is 0% static checking since 100% is too painful, then an alternative that gives you to 95% static checking with great ergonomics looks like a win. And we might still get to 100% in the future.
240
+
Put another way: If the status quo is 0% static checking since 100% is too painful, then an alternative that gives you 95% static checking with great ergonomics looks like a win. And we might still get to 100% in the future.
0 commit comments