Exceptions - lrytz/efftp GitHub Wiki

The exceptions effect domain is enabled using the compiler option -P:effects:domains:exceptions.

Exceptions checking works like checked exceptions in Java. The main difference is that Scala supports lightweight syntax for effect-polymorphism using relative effect annotations.

Note: the current implementation does not distinguish between checked and unchecked exceptions, see see #12.

Effects are annotated using the @throws annotation

  • Purity is annotated as @throws[Nothing] (or @pure, but this annotation ranges across all effect domains)
  • If a method can throw multiple kinds of exceptions it can be either annotated with @throws[E1 | E2], or with @throws[E1] @throws[E2]
def g(x): Unit @throws[E1] = { ... }
def f(x: Int): Unit @throws[E1 | E2] = {
  if (x < 0) throw new E2
  else g()
}

Catching Exceptions

The compiler plugin will compute which effects are masked by try-catch clauses:

def h(x: Int): Unit @throws[E1] = try {
  f(x)
} catch {
  case e: E2 => ()
}

However, unlike in Java, the catch clause in Scala supports not only type tests, but arbitrary patterns. In case the plugin cannot determine if an exception will be caught or not it will do a conservative approximation:

catch {
  case e: E2 if condition(e) =>
}

In this example, the exception E2 will not be masked - it might be caught or not, depending on the evaluation of condition(e).

Limitations of effect inference can be overcome using effect casts.