-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Examples from the reference don't work? #23457
-
First time writing Scala. Trying the examples in https://docs.scala-lang.org/scala3/reference/experimental/cc.html, using Scala 3 built from source (commit 665f6d7).
In the section "By-Name Parameter Types" we have these two functions
def f1(x: => Int): Int =
123
def f2(x: -> Int): Int =
123
The text says the first one should allow captures but the second one doesn't. But this works:
class MyException extends Exception, Capability
def f1(x: => Int): Int =
123
def f2(x: -> Int): Int =
123
@main
def hello(): Unit =
f1(if true then throw MyException() else 1)
f2(if true then throw MyException() else 1)
Shouldn't the second call be rejected? Am I doing it wrong?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 2 comments
-
Exceptions are only tracked under the language import language.experimental.saferExceptions
. So I think the reference needs to be updated. Here's a simpler example that shows purity checking works for by-name arguments:
import language.experimental.captureChecking def f1(x: => Int): Int = 123 def f2(x: -> Int): Int = 123 def hello(c: Object^): Unit = f1({ println(c); 1 }) f2({ println(c); 1 })
Compiling this gives
-- [E007] Type Mismatch Error: test.scala:14:5 ---------------------------------
14 | f2({ println(c); 1 })
| ^^^^^^^^^^^^^^^^^
| Found: () ?->{c} Int
| Required: () ?-> Int
|
| longer explanation available when compiling with `-explain`
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks @odersky for the answer.
I'm trying to understand how the capability-based tracking of exceptions scale as you combine functions that use capabilities.
I have this:
import caps.Capability
import java.io.FileOutputStream
import language.experimental.captureChecking
import language.experimental.saferExceptions
class E1 extends Exception, Capability
class E2 extends Exception, Capability
class E3 extends Exception, Capability
class E4 extends Exception, Capability
def f1(): Unit throws E1 =
throw E1()
def f2(): Unit throws E2 =
throw E2()
def f3(): Unit throws E3 =
throw E3()
def f4(): Unit throws E4 =
throw E4()
def f5(): Unit throws E3 | E4 =
f3()
f4()
// def f6(): Unit^{f5, f2, f1} =
def f6(): Unit throws E1 | E2 | E3 | E4 =
f5()
f2()
f1()
Ideally I shouldn't have to list all of the exception types in f6
. From the capture checking page I thought I could do something like:
def f6: Unit^{f5, f2, f1} =
f5()
f2()
f1()
But this generates a few errors.. Is something like this allowed? What's the right syntax?
Thanks again.
Beta Was this translation helpful? Give feedback.