An idiom for cleaner pimping of libraries in Scala

In dynamic languages like JavaScript and Ruby you can modify existing classes, including system classes, with extra methods. This can be a very handy, if dangerous, technique.

Scala, being a static language does not allow this same technique. But it does allow the use of implicit functions to get the same effect. For example the standard idiom to add sine and cosine methods to the Double class is

class PimpedDouble(x:Double){
  def sin = Math.sin(x)
  def cos = Math.cos(x)
}
implicit def pimpDouble(x:Double) = new PimpedDouble(x)

This has the effect of adding sin and cos methods to Double, though what is actually happening is that Double values are automatically converted to PimpedDouble values when doing so would correctly compile.

This is very clever and very handy, but the idiom is a little clumsy, compared to most of Scala's elegant features. It is annoying to have to invent two names PimpedDouble and pimpDouble that are never referred to anywhere else in the code.

Can we do better? Yes we can. We can make the extra class be an anonymous class, which leaves only one arbitrary unreferenced name and also reduces the size of the code.

implicit def pimpDouble(x:Double) = new {
  def sin = Math.sin(x)
  def cos = Math.cos(x)
}

That seems a lot nicer to me.

Using either of the above techniques you can now do things like

  val x = 0.5 cos
  val y = 0.5 sin

which is taking the cosine and sine of the Double value 0.5

(Thanks to Daniel whose stackoverflow posting first brought this idiom to my attention.)

Comments

this uses dynamic invocation

Unfortunately, this clean idiom is low on performance. The disassembly of the byte code to Java is (sorry for the loss of formatting):

public Object pimpDouble(double x$1)
{
return new Object() {
public double cos() {
return Math..MODULE$.cos(this.x$1);
}

public double sin()
{
return Math..MODULE$.sin(this.x$1);
}
};
}

and the invocation looks like:

private pimp$()
{
MODULE$ = this;

this.f = 2.0D;
Object qual1 = pimpDouble(f()); Object exceptionResult1 = null;
try { exceptionResult1 = reflMethod$Method1(qual1.getClass()).invoke(qual1, new Object[0]); Predef..MODULE$.println((Double)exceptionResult1); return; } catch (InvocationTargetException localInvocationTargetException) { throw localInvocationTargetException.getCause();
}
}

Performance implication of using this idiom

Thanks ittayd for pointing this out. Indeed the new { } construct creates a structural type which means that all the calls are invoked via reflection.

So unfortunately this is not a good idiom to use. For efficiency it is better to create an explicitly named class.

> omeprazole 40 mg price - buy misoprostol and mifepristone
- valtrex buy online no prescription - where to buy asacol - cell spy phone - generic levitra -