Analytics

Sunday, February 24, 2013

Implicit Values

Scala implicits are an interesting feature that could certainly fill up multiple blog posts, but in this one I'm just going to touch on how implicit values work at a high level and why you might use them. In the context of values and parameters, the implicit keyword can mean two things:
  • the value or parameter is implicit in the current scope; or
  • the parameter list is implicit and can be omitted provided there are corresponding implicit values in the scope of the method call.
For example, consider the following methods:

Here, foo is an example of a method whose parameter list (just one parameter in this case) is implicit. That means we can call it without any parameters if we have an implicit String in scope. The bar and baz methods show two ways of doing this: bar declares its parameter implicit just like foo, which causes it to be implicit in the current scope, while baz declares an additional implicit value that lives in the scope. Lastly, the qux method demonstrates that you can still pass the parameter explicitly.

Depending on your background and preferences, this might seem like either one of the most useful language constructs or one of the scariest. Implicits are very powerful for building frameworks like Play (more on this later) but at the same time can result in code that is very hard to understand due to the difficulty of tracing the usages of state through the code. Because Scala is a type-safe language, however, you at the very least get static type checking so that you don't accidentally end up in a complete mess of improperly typed implicits. For example, these two methods will not compile (thankfully):


The foobar method pretty clearly does not have an implicit String in the current scope which means foo cannot be called. The second case with fubar is a little more subtle, both in syntax and in semantics. The implicit keyword is applied to a parameter list rather than a parameter (the reasons for this are not clear to me), so both String parameters are implicit in the scope of the method. The result, however, is that the implicit String passed to foo is now ambiguous; the Scala compiler won't do anything crazy like arbitrarily choose one, but instead give you an error saying that you tried to do something very dangerous. So implicits are Scala's type-safe way of pretending like the language is more dynamic than it really is.

In general, I don't really advocate using implicits because it's quite easy to get yourself into trouble doing so, but there are cases in which it makes sense. As I mentioned earlier, the Play framework for building web applications is one instance where the use of implicits is convenient. When handling a web request, there are some things which are conceptually always in scope, such as the actual HTTP request or the currently authenticated user (as an option, of course). It can be burdensome to pass these values around constantly, especially between views, and the pain is noticeable if you're coming from something like Django. By leveraging implicits, you can just declare the variables you expect to be in scope at the top of the view and use them freely; as long as they are always declared implicit, the compiler will do the rest for you.

To summarize, implicits allow Scala programmers to have the illusion of working with a more dynamic language. They are powerful but can be dangerous, and as such should be used sparingly.

2 comments:

  1. do you mean qux in "Lastly, the baz method demonstrates that you can still pass the parameter explicitly." ?

    ReplyDelete