Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't _ be used to indicate an unused/ignored argument in a method override?

Tags:

scala

Consider:

trait Validation {
  def isValid(str: String): Boolean
}
class AlwaysValid extends Validation {
  override def isValid(_: String) = true
}

yields

<console>:1: error: identifier expected but '_' found.
       override def isValid(_: String) = true

Any ideas why? Or is that just something the language designers missed?


Maybe it's about named argument passing but this would only apply to non-overrides as overrides auto-"inherit" the argument names from the overridden method anyway, so this can't be it:

trait Foo {
  def bar(arg0: String): String
}
class Baz extends Foo {
  override def bar(blabla: String) = "hello"
}

new Baz().bar(arg0 = "world")  // works, even though the arg name is blabla in Baz

Furthermore: _ is allowed in lambdas, even multiple times:

scala> val x: Int => Int = _ => 3
x: Int => Int = <function1>

scala> val x: (Int, Int) => Int = (_, _) => 3
x: (Int, Int) => Int = <function2>
like image 510
Erik Kaplun Avatar asked Nov 10 '14 13:11

Erik Kaplun


3 Answers

Because you can use parameters names when calling the method.

Scala allows you to change the name of a parameter when overriding (discouraged though) but you always need to provide a name for the caller to use if they so want.

like image 74
vptheron Avatar answered Oct 24 '22 10:10

vptheron


I think it's simply a grammar issue.

_ is a special identifier in scala, and it's usage is allowed a in a well-defined set of cases, such as lambdas, partial method application and pattern match.

I didn't look into the language spec, but it's safe to assume that a method parameter is expected to be a name identifier and _ is just not a valid one.

like image 38
Gabriele Petronella Avatar answered Oct 24 '22 09:10

Gabriele Petronella


Here's a somewhat more detailed explanation of what's going on:

  1. the reason why _ works with lambdas is that lambdas can never have named arguments anyway.
  2. in case of polymorphic calls to subclass (Baz) instances via references of the parent class type (Foo), Scala will simply "inherit" the parent class method names (arg0) into the subclass so polymorphic calls don't see the altered name blabla in Baz#bar;
  3. however, the subclass method still needs to be callable directly as well, so it does need to provide valid names for its arguments, so _ won't work for obvious reasons; it's also recommended that those match the parent class method names which were overridden for reasons of clarity.
like image 44
Erik Kaplun Avatar answered Oct 24 '22 10:10

Erik Kaplun