Tuesday, March 15, 2011

Annotate your type classes (@implicitNotFound)

This is a real quick post saying that as of 2.8.1, everyone should be annotating their type class traits for better error messages. Obviously, those of us who are supporting 2.8.0 or earlier are left out.


Here's an example REPL session:

Welcome to Scala version 2.9.0.r24384-b20110305105029 (OpenJDK 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import annotation.implicitNotFound
import annotation.implicitNotFound

scala> @implicitNotFound(msg = "Cannot find Serializable type class for ${T}") trait Serializable[T]
defined trait Serializable

scala> def foo[X : Serializable](x : X) = x
foo: [X](x: X)(implicit evidence$1: Serializable[X])X

scala> foo(5)
:11: error: Cannot find Serializable type class for Int
       foo(5)
          ^

The annotation has very little documentation, but apparently supports ${TypeName} templates to inject the names of types the compiler is looking for. I believe you can also use this implicit on types with no type parameters.

Happy hacking everyone!

5 comments:

Kannan Goundan said...

Why is it hard for the compiler to come up with this error message on its own?

J. Suereth said...

It's a matter of intended usage. This lets you edit an error message to show the intent of a class. The compiler only knows it was looking up an implicit and failed, so the error message is generic.

In general, I think good error reporting is often taken for granted. It's not a simple thing when the utility, implicit lookup, is so general.

Seth Tisue said...

Without the annotation, what does the error look like?

J. Suereth said...

scala> foo(5)
:8: error: could not find implicit value for evidence parameter of type Serializable[Int]
foo(5)

Fixing the error message with additional information can still be desirable. We tend to link documentation at google (e.g. describing the type class and its function).

Ramesh Mandaleeka said...

The new message should compose on the run time message. So we wont loose what it is saying. May be a mechanism to turn on and off this behavior will be nice.