Understanding Scala Implicits

Many languages make use of implicit conversions. Scala is the only language I know of which makes implicit definitions a feature.

It is very easy to understand an implicit conversion since most programming languages do this already for you. Here are two examples (AS3/Java):

trace("Implicitly converted: "+1)
System.out.println("Implicitly converted: "+1);

We only have to care about the expression "Implicitly converted: "+1 which will result in “Implicitly converted: 1″. Why does this happen? We have a string on the left hand side of the expression and an integer on the right hand side. When the compiler of your choice needs to emit code for this kind of expression it will widen the type of both operands. In this case the resulting type would be String since an implicit conversion from integer to String exists in both ActionScript and Java. If no such conversion exists you would probably get a compile time error.

The compiler inserts this conversion for you. In this example we can make use of an explicit conversion:

trace("Explicitly converted: "+1.toString())
System.out.println("Explicitly converted: "+Integer.toString(1));

Here we specify that we really want to concatenate two strings which is of course a tedious task. We are lucky to have implicit conversions. Whenever you want to go from type A to B a compiler either inserts an implicit conversion for you or tells you that it cannot do it with an error message.

In certain scenarios you might want to use implicit conversions for your own types. In ActionScript I might want to go from Sprite directly to BitmapData.

Here is an example. Please do not do this at home. There is a of course a much better way (and less memory intensive) to do a hit test on a Sprite.

function hitTest(bitmapData: BitmapData, x: int, y: int): Boolean {
  return bitmapData.getPixel32(x, y) != 0x00000000
}

const sprite: Sprite = new Sprite()
hitTest(sprite, 1, 2)

Now this code would not compile of course since hitTest(sprite, 1, 2) is incorrect. The compiler would tell you that it expects a BitmapData as the first parameter. Let us fix the example:

function hitTest(bitmapData: BitmapData, x: int, y: int): Boolean {
  return bitmapData.getPixel32(x, y) != 0x00000000
}

function toBitmapData(displayObject: DisplayObject): BitmapData {
  const result: BitmapData = new BitmapData(
      displayObject.transform.pixelBounds.width,
      displayObject.transform.pixelBounds.height)

  const matrix: Matrix = displayObject.transform.matrix

  matrix.tx = matrix.ty = 0.0
  result.draw(sprite, matrix)

  return result
}

const sprite: Sprite = new Sprite()
hitTest(toBitmapData(sprite), 1, 2)

Now it works but every time we would want to go from Sprite to BitmapData we have to insert our new toBitmapData function.

And here is what makes Scala so special. You can tell the compiler that toBitmapData may be used as an implicit conversion.

Here is the same example in Scala without making use of implicit conversions:

def hitTest(bitmapData: BitmapData, x: Int, y: Int) =
  bitmapData.getPixel32(x, y) != 0x00000000L

def toBitmapData(displayObject: DisplayObject) = {
  val result = new BitmapData(
      displayObject.transform.pixelBounds.width,
      displayObject.transform.pixelBounds.height)
  val matrix = displayObject.transform.matrix

  matrix.tx = 0.0
  matrix.ty = 0.0

  result.draw(sprite, matrix)
  result
}

val sprite = new Sprite()
hitTest(toBitmapData(sprite), 1, 2)

Not so different. However we can annotate the toBitmapData definition as implicit and the code would look like this:

def hitTest(bitmapData: BitmapData, x: Int, y: Int) = ...

implicit def toBitmapData(displayObject: DisplayObject) =
  ...

val sprite = new Sprite()
hitTest(sprite, 1, 2)

So I think now it is time to take a deep breath. If you think that this is dangerous you should keep two more things in mind. First of all the compiler will only use implicit conversions that are in the current scope of your method. This means if you define an implcit conversion in class A and want to use it in B you have to import it. Also it could happen that you have two implicit conversions in the same scope. Since the compiler does not know which one it should pick it will give you an error message. This makes a lot of sense.

So in the end it is a great way to enable a specific implicit conversion for parts of your code. You are also able to use an import statement only in a method body like this:

def myComplexMethod(a: A) = {
  import ImplicitConversions.fromAtoB
  ...
}

But this is just the one part about implicit conversions. In my A Year Of Scala post I did mention that implicit conversions can be used to build domain specific languages.

Right now we get rid of our explicit casts which is nice but a true DSL needs obviously much more. For instance I might want to say 0xff00ff.toHexString instead of toHexString(0xff00ff). This can also be achieved with implicit conversions. And this is not what you might already know from Java or ActionScript.

Whenever we invoke a method on an object, and the object’s type does not support that method, but an implicit conversion to a different type containing the method exists, it is applied. So remember the Sprite and BitmapData example?

This would be illegal in ActionScript:
sprite.getPixel(x, y)

This would be legal:
toBitmapData(sprite).getPixel(x, y)

And with an implicit toBitmapData method in Scala we get:
sprite.getPixel(x, y)

In fact this is quite simple. So in case you did not notice: this is also statically typed monkey patching. And because you can omit dots and parenthesis we get code like G("vertex1" --> "vertex2"). Where is the implicit conversion? A string has no --> method defined but we could define an implicit conversion to a class VertexPair that has the --> method defined.

Last but not least there are also implicit parameters and values in Scala. In fact only an implicit value may be used as an implicit parameter.

If you are always carrying the same parameter around you, why not define it as implicit? An OpenGL context for instance. render(float t, GL11 gl) is some kind of code that might occur very often. Let us make the gl parameter implicit.

def render(t: Float)(implicit gl: GL11) = ...

Now if you do not have an implicit value available, you can still call this method via render(1.0f)(gl). But if you declare a GL11 object once as implicit it can be passed down the chain very easy.


implicit val gl = framework.getOpenGLContext()
render(1.0f)
render(1.5f)

Now if you call a method inside render that needs an implicit GL11 parameter as well you would not have to declare it as implicit again. But the same rules apply here. If there are two implicit GL11 typed objects available the compiler will complain.

I hope this makes working with implicit conversions and values a little bit easier.

5 Responses to “Understanding Scala Implicits”


  • Thanks for great Scala posts q: Hope you’ll continue.
    Scala is a great language, but is indeed kind of hard.

  • Thank you for your articles about scala. I always learn something new from them.

  • It’s a bit offtopic, but why do you use const so often? Is there a performance/memory gain from using it?

  • Hey my name is Karl too, and I too wonder that!

    Just seemed weird.

  • Karl & Karl: There is of course performance gain on good virtual machines. The last test I did on the AVM2 was 3y ago and it did not matter. It might have changed though.

    But besides that it is a good habit to define variables that do or should not change constant.

Leave a Reply