3

Why does doSmth(() => s) not compile? Why does the rest of the code output "value"? Is there a way to call the second function(with call-by-name parameter)?

object Test {
  def main (args: Array[String]){
    lazy val s: String = ""
    doSmth(s)
    doSmth("")
    doSmth(() => s)
  }

  def doSmth(p: String): Unit = {
    println("value!")
  }
  def doSmth(p: => String): Unit = {
    println("call by name!")
  }
}
ilinum
  • 464
  • 4
  • 11

1 Answers1

0

The following code works and compiles as expected:

def doSmth(p: String): Unit = {
  println("value!")
}
def doSmth(p: () => String): Unit = {
  println("call by name!")
}

lazy val s: String = ""
doSmth(s)
doSmth("")
doSmth(() => s)

Note that if you have two versions of the method, one which is by-name and one which is by-value, there is no way for Scala to know which one you mean. Instead above, the second version of the method takes a function from unit to string.

mattinbits
  • 10,370
  • 1
  • 26
  • 35
  • well, even with the original version of the code, `doSmth("")` outputs "value!" – ilinum Sep 01 '15 at 09:17
  • One of the questions I was asking whether I could call `doSmth()` and make it output "call by name!" without changing the original function – ilinum Sep 01 '15 at 09:18
  • If you have doSmth defined as taking both a call by value String and a call by reference String, then the compiler can't determine which version to execute. Whereas in my example, the second version of doSmth takes a function from unit to string, then you can choose to pass a string, or a function which yields a string, the compiler can tell the difference. – mattinbits Sep 01 '15 at 09:27
  • If the compiler was not able to determine which one to call, it would not compile. – ilinum Sep 01 '15 at 09:30
  • `doSmth(() => s)` does not compile. However, `doSmth("")` and `doSmth(s)` does compile, so compiler does not which function to call. – ilinum Sep 01 '15 at 09:31
  • doSmth(() => s) does not compile because () => s is a function from Unit to s and you have not instance of doSmth which takes a function with that signature as a parameter. `=> s` and `() => s` are not the same thing. – mattinbits Sep 01 '15 at 09:37
  • All right, thanks! That makes sense. However, I still do not understand, how can I make a call to `def doSmth(p: => String): Unit = println("call by name!")` when `def doSmth(p: String): Unit = println("value!")` is in scope – ilinum Sep 01 '15 at 11:10
  • Basically, you can't. So, it's not useful to have both. – RD1 Apr 01 '16 at 06:27