Posted by & filed under Journals.

Here’s the tl;dr

Method overloading sucks in Scala because it actually detracts from your flexibility. An implicit conversion is a feature of Scala that lets the compiler look up how to convert objects between types at compile time.

Let’s say I define a method with the following signature:

def doSomething( action: Action )


Somewhere else in the code I write:

val idea: Idea = // some idea
doSomething( idea )


If Idea is a subtype of Action most languages will have no problem, including Scala. If Idea is not a subtype of Action this would be a compile-time error in languages like Java. The Scala compiler, however, doesn’t give up just yet. Instead of just throwing a type error, the Scala compiler searches for an implicit conversion between Idea and Action.

An implicit conversion is just a method marked implicit that has the right signature, in this case

implicit def anyNameWillDo( idea: Idea ): Action


The only caveat is that the compiler must be able to find the conversion along a pre-determined search path. The compiler will check, in order, the local scopes, followed by the companion objects of Action and Idea. Only if no implicit conversion can be found will the compiler issue a type error.

The problem with operator overloading, and why is sucks, is because overloaded methods interfere with implicit conversions. Let us overload the doSomething method to accept both an Action and Idea.

def doSomething( action: Action )
def doSomething( idea: Idea )


Now our implicit conversion, which we had full control over will no longer work. We’re stuck with whatever conversion the overloaded method uses.

Adding new overloaded methods requires modifying the target class, which is not always possible.

By using implicit conversions your code will look cleaner. The class containing the method doSomething need only implement the method that responds to an Action. All conversion code is located elsewhere in the code base.

Implicit conversions are determined at compile time. Typically default conversions are in the companion objects or imported from a package. If you don’t like the default conversion, bring another implicit into a nearer scope than the default.

Methods containing multiple arguments can mix and match conversions. Say we define:

def doThreeThings( first: Action, second: Action, third: Action )


Implicit conversions let us do any of the following:

doThreeThings( idea, idea, idea )
doThreeThings( idea, idea, action )
doThreeThings( idea, action, idea )
doThreeThings( idea, action, action )
doThreeThings( action, idea, idea )
doThreeThings( action, idea, action )
doThreeThings( action, action, idea )
doThreeThings( action, action, action )


To accomplish the same thing with method overloading, we would require eight separate methods.

### Just Say No

As Tim points out below, since Scala supports default method arguments, we can avoid the following:

doSomeThings( action: Action )
doSomeThings( action: Action, action: Action )
doSomeThings( action: Action, action: Action, action: Action )


Imagine how many methods we would need to define if we wanted to also accept Idea types! We would need 14 separate methods.

• Tim

You for about default arguments, e.g. def foo(arg1: String = “Bob”, arg2: SomeType = someValue) removes another big chunk of the use case of overloading.

• http://www.underflow.ca/ Jacob Groundwater

Added this to the end, good point.

• Anonymous

I’d say you’re a bit confused.  At the very least, your example makes no sense.  If you have a doSomething(Action) and a doSomething(Idea) then this is arguably quite superior to an implicit conversion, since the implicit conversion is not tied to the context of “doSomething”; it will convert no matter what.  It doesn’t matter whether the conversion should be applicable or not, it will do it anyway.

The fact that you’re mixing implicit conversions with overloading in an odd way, makes it… well, odd.  Nobody should be surprised by this.  Use implicit conversions for what they’re intended for, and use overloading for what’s intended for.  If you purposely make them clash with each other, then you’ve discovered what a lot of people already know: they’re not intended for the same purpose.

• http://www.underflow.ca/ Jacob Groundwater

If you really need your class to be in control of how a type is used, use a method with a different name. It is trivial to do, and doesn’t interfere with implicit conversions. This is much less ambiguous as to intention. I’m not saying you have to use implicits, but using method overloading will interfere with anyone who wishes to use them.

There is no necessary use case for method overloading other than convenience. In Java this was great since you do not need to memorize a lot of method names. In Scala, there are much better ways.

Target-typed implicit conversions (such as “implicit def a2i(a: Action): Idea) are a design error in Scala. The reason that these are a design error is that they can inadvertently be applied when inappropriate, and are obfuscatory. Implicit conversions are suitable for implementing the “pimp my library” pattern, but not for the purpose you suggest in this article; and, indeed, such conversions will be restricted behind flags after SIP-18 goes through.

In short, don’t do this. If you want to convert from Idea to Action, do so explicitly; add .toAction to Idea (perhaps via a pimp-my-library implicit) and call as doSomething(idea.toAction)

• http://www.underflow.ca/ Jacob Groundwater

I can’t find anything to support your assertion that they are a design error.

An implicit conversion of the kind I used is pretty much as explicit as it gets. In fact, it’s exactly what is suggested by “Pimp my library” (http://www.artima.com/weblogs/viewpost.jsp?thread=179766). The conversions used in my example are akin to (val x:Int = “2″).

Most IDEs will tell you exactly what type your object is, and what type is expected. It should also show you the implicit conversion used.

Your suggestion still requires implicit conversion, but what I consider the less obvious kind. Where .toAction is attached to some helper class with an implicit conversion. Unless you suggest adding a .toAction method to all Idea classes, which I would consider a design error.
As for SIP-18, it looks pretty controversial so I’ll wait until it gets implemented before giving it much weight. Even when it gets implemented, it’s not a problem, you would just explicitly mention that you wish to add implicit conversions. This does not mean they are discouraged, any more than importing a collection is discouraged, rather they are just trying to organize the language features of a rapidly growing platform.

I would concede that placing the implicit conversions within the companion object might confuse an newbie scala developer who wasn’t sure why their code was compiling what looks like an obvious type error. I am however arguing against method overloading, and am asserting that there are better, cleaner, more controllable ways.

• Tim

Another blog I follow says that SIP-18 is a terrible idea:  http://blog.tmorris.net/sip-18-is-just-another-bad-idea-serving-nobody/

SIP-18 is a terrible idea, but that doesn’t make the idea presented here any better

• http://www.underflow.ca/ Jacob Groundwater