overloaded methods with default arguments

29 views
Skip to first unread message

Russ P.

unread,
Feb 26, 2015, 7:33:26 PM2/26/15
to scala...@googlegroups.com

scala> class foo {
     | def bar(i: Int, j: Int=0) = i + j
     | def bar(s: String, j: Int=0) = s
     | }

<console>:7: error: in class foo, multiple overloaded alternatives of method bar define default arguments.
       class foo {
             ^

Will someone please explain why this should not compile? A proper call to these methods cannot possibly be ambiguous since the first argument is a completely different type. Thanks.

Som Snytt

unread,
Feb 26, 2015, 8:22:44 PM2/26/15
to Russ P., scala-user
It's a limitation of the encoding, since the method name and param position make up the name of the method that provides a default value.

There was one case last year where the rule was relaxed (details escape me) so maybe it will become smarter over time. (That's just wild optimism.)

scala> class X { def bar(i: Int, j: Int=0) = i + j ; def bar(s: String, j: Int) = s }
defined class X

scala> :javap -public X
Compiled from "<console>"
public class X {
  public int bar(int, int);
  public java.lang.String bar(java.lang.String, int);
  public int bar$default$2();
  public X();
}



--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Russ P.

unread,
Feb 26, 2015, 8:37:20 PM2/26/15
to scala...@googlegroups.com, russ.p...@gmail.com
It's forcing me to generate longer, inelegant method names. I can't believe I'm the only one who wants this fixed!

Rex Kerr

unread,
Feb 26, 2015, 8:53:45 PM2/26/15
to Russ P., scala-user
No, you're not the only one.  I complained about it at length about three years ago.  Still bugs me from time to time.  It makes writing convenience methods inconvenient, which is not a tradeoff I like to have to make.

  --Rex

Haoyi Li

unread,
Feb 26, 2015, 9:16:10 PM2/26/15
to Rex Kerr, Russ P., scala-user
Typeclasses work great for this sort of thing at the cost of more implicits and verbosity... but at least the callsites look nice

Jason Zaugg

unread,
Feb 26, 2015, 10:31:13 PM2/26/15
to Haoyi Li, Rex Kerr, Russ P., scala-user
We can loosen the restriction (a little) as described in https://issues.scala-lang.org/browse/SI-8161

Under that proposal, you could define defaults in overloaded methods of different arities. This wouldn’t help your example directly, unless you were willing to add a dummy parameter to one of the methods.

The restriction stems from the constraints of separate compilation and the way that defaults in Scala can be overridden in subclasses.

-jason


Sent from Mailbox

Russ P.

unread,
Feb 27, 2015, 12:07:15 AM2/27/15
to scala...@googlegroups.com, haoy...@gmail.com, ich...@gmail.com, russ.p...@gmail.com
If adding a dummy argument with a default value solved the problem, I would be happy, but that doesn't seem to work. I also tried adding a mandatory dummy argument, and that didn't work either. What exactly is the workaround that you are suggesting, Jason? Can you provide a simple example? Thanks.

Jason Zaugg

unread,
Feb 27, 2015, 12:09:04 AM2/27/15
to Russ P., scala...@googlegroups.com, haoy...@gmail.com, ich...@gmail.com, russ.p...@gmail.com
Sorry, I wasn’t clear. The ticket I linked to has not been implemented yet, so for now you have to restructure your code by renaming a method, as you initially feared.

-jason


Sent from Mailbox

Russ Paielli

unread,
Feb 27, 2015, 12:37:44 AM2/27/15
to Jason Zaugg, scala-user, Haoyi Li, Rex Kerr
You were clear, but I should have read it more carefully. Now I see "Under that proposal ..." Oops.

Russ Paielli

unread,
Feb 27, 2015, 2:18:58 PM2/27/15
to Jason Zaugg, scala-user, Haoyi Li, Rex Kerr
One more question, Jason. If your proposal is implemented, what will the workaround be for methods of the same arity? Will a dummy argument with a default value solve the problem, or will a dummy mandatory argument be required? The former would be far preferable, of course, because it would not affect he call site.

And when do you expect this to be done?

Also, does Martin intend to eventually correct this problem, or we will we have to live with the workaround in perpetuity? Thanks.

On Thu, Feb 26, 2015 at 9:08 PM, Jason Zaugg <jza...@gmail.com> wrote:

Nils Kilden-Pedersen

unread,
Feb 27, 2015, 4:06:28 PM2/27/15
to Russ P., scala-user
On Thu, Feb 26, 2015 at 7:37 PM, Russ P. <russ.p...@gmail.com> wrote:
It's forcing me to generate longer, inelegant method names. I can't believe I'm the only one who wants this fixed!

I usually solve it the Java way, i.e. overloaded methods with varying args. It's boilerplatey and inelegant, but it beats having different names (IMO). 

Jon Pretty

unread,
Mar 1, 2015, 6:36:40 AM3/1/15
to Russ P., scala...@googlegroups.com
Hi Russ,

Haoyi's suggestion would work for you. Here's an implementation:

  trait OverloadResolver[T] {
    def apply(t: T, j: Int): T
  }
  object OverloadResolver {
    implicit val intOverload = new OverloadResolver[Int] {
      def apply(t: Int, j: Int) = t + j
    }
    implicit val stringOverload = new OverloadResolver[String] {
      def apply(t: String, j: Int) = t
    }
  }

  class Foo {
    def bar[T](t: T, j: Int = 0)(implicit or: OverloadResolver[T]): T =
      or(t, j)
  }

As you can see, it's a lot of extra code for a relatively tiny difference...

Cheers,
Jon

--
Reply all
Reply to author
Forward
0 new messages