The Artima Developer Community
Sponsored Link

Ideas, Languages, and Programs
Pimp my Library
by Martin Odersky
October 9, 2006
What to do if you are stuck with existing libraries and API's.


There's a fundamental difference between your own code and libraries of other people: You can change or extend your own code, but if you want to use some other libraries you have to take them as they are.

A number of constructs have sprung up in programming languages to alleviate this problem. Smalltalk has meta classes, Ruby has modules. These are very powerful, but also dangerous, in that you modify the behavior of a class for an entire application, some parts of which you might not know. C# 3.0 has method extensions, which are more local, but also more restrictive in that you can only add methods, not fields or interfaces to a class.

Scala has implicit parameters and conversions. They can make existing libraries much more pleasant to deal with. A particularly nice example is a wrapper for simplifying JDBC, written by Ross Judson (I misattributed this to Jamie Webb in the original version of the blog; my apologies).

The rest of this blog explains what implicits are (you can skip it if you know it already, or if you don't care). Say you have a value x of type Array[int] and you want to assign this value to some variable of type String:

var v: String = x

Array[int] does not conform to String, so normally this would give a type error. However, you can define a conversion function from arrays of arbitrary element type T to String, like this:

implicit def array2string[T](x: Array[T]) = x.toString

(Yes, arrays have a usable toString method in Scala!). The only non-standard aspect of this function is its implicit modifier, which labels it as an implicit conversion. If such an implicit conversion is visible at the point of an otherwise illegal assignment, the conversion is automatically inserted. So the above assignment would be expanded to:

var v: String = array2string(x)

Implicit conversions can also be applied in other situations. For instance they can be applied when selecting a member of some value which is undefined in its type. An example is an append operator on arrays, to be used as in the following:

val x = Array(1, 2, 3)
val y = Array(4, 5, 6)
val z = x append y

Scala parses the last expression as a method call: x.append(y). The problem is that Scala's arrays are directly mapped to Java's arrays, and there is no append method in either type! However, implicit conversions can help. We need to define a new class, say RichArray, which defines an append method (and which might also define other methods we want to add to the Array type):

class RichArray[T](value: Array[T]) {
  def append(other: Array[T]): Array[T] = {
    val result = new Array[T](value.length + other.length)
    Array.copy(value, 0, result, 0, value.length)
    Array.copy(other, 0, result, value.length, other.length)

Now, all that remains is to define an implicit conversion from plain arrays to rich arrays:

implicit def enrichArray[T](xs: Array[T]) = new RichArray[T]

With this conversion, we have effectively enriched Java's array class with an append method.

Talk Back!

Have an opinion? Readers have already posted 32 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Martin Odersky adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Martin Odersky is the inventor of the Scala language and professor at EPFL in Lausanne, Switzerland. In 2008, he was appointed fellow of the ACM for his contributions to the fusion of functional and object-oriented programming. He believes the two paradigms are two sides of the same coin, to be unified as much as possible. To prove this, he has worked on a number of language designs, from Pizza to GJ to Functional Nets. He has also influenced the development of Java as a co-designer of Java generics and as the original author of the current javac reference compiler.

This weblog entry is Copyright © 2006 Martin Odersky. All rights reserved.

Sponsored Links


Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use