Multiple Overloaded Alternatives and Default Arguments

Dear all,

Why does the overload resolution fail in the following case?

object bad {
  class B
  class D1 extends B
  class D2[T1 <: B, T2 <: B] extends B
  def f[T <: B](t: T, str: String = "") {println("general one")}
  def f[T1 <: B, T2 <: B](t: D2[T1, T2], str: String = "") {println("specific one")}

The error that Scala 2.11.8 (Java HotSpot™ 64-Bit Server VM, Java 1.8.0_121) gives me is as follows:

 <console>:11: error: in object bad, multiple overloaded alternatives of method f define default arguments.
       object bad {

The two overloads should have different signatures. And, I don’t get the same error when there are no default arguments. So, what’s all that fuss about the default arguments?


Looking at the section of the Scala spec for default arguments, we see that it explains how default arguments are encoded as methods named <methodname>$default$<position>. In order to have multiple overloads with defaults you would need to overload the magic default methods, which would only work if they had distinct types.

Probably someone decided that allowing the cases that wouldn’t actually cause conflicts would yield complicated rules that would be hard to understand, while just limiting default arguments to a single instance of an overloaded method is much easier to explain.

1 Like

Thank you for the explanation and pointing out the exact place in the spec. Using those two, I now do understand what’s going on. Nevertheless, I still think that makes no sense. Any way Scala can improve that?


Relevant Stack Overflow question; the responses include one from Martin Odersky:

While it would be nice to combine overloaded methods and default arguments, the slight increase in verbosity from adding a little type information to the method name (e.g., readString, readFile) is, in my opinion, a small price to pay for the power of default arguments.


Hi Dan,

The thread from Stack Overflow was indeed enlightening. The design decision, however, doesn’t still make sense to me. In particular, Martin says:

It would be very hard to get a readable and precise spec for the interactions of overloading resolution with default arguments.

What’s the point about readability here? How many times per version would the compiler vendor want to debug the name mangling after all? And, proper multi-paradigm languages like C++ and D have been doing that for decades now…