3

I am new to scala language, therefore I will be grateful if someone could explain me this code-snippet :

object C  {

  def main(args: Array[String]) = {
    measure("Scala"){
      println("Hello Back")
    }
  }

  def measure(x: String)(y: => Unit){
   println("Hello World " + x)
  }
}

Console output :

Hello World Scala

My question is why the program didn't print Hello Back as well? Also is the function/object ;whose body is the instruction println("Hello Back"); stored somewhere on the heap?

sasuke
  • 145
  • 1
  • 10
  • When you want to understand a basic language feature, the chances are pretty big that someone has already asked that. – Jasper-M Nov 22 '16 at 09:40

2 Answers2

6

What distinguishes by-name parameters from normal ones is that the argument expression is evaluated whenever the parameter is used. So if you use it twice, the expression is evaluated twice. And if you don't use it at all, it's never evaluated.

So in your case "Hello Back" is not printed because you never use y.

Also is the function/object ;whose body is the instruction println("Hello Back"); stored somewhere on the heap?

The generated code for by-name parameters is the same as for functions, so it will create a function object on the heap.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • Hello @sepp2K, I have a quick question. What is datatype of `y` when I define `y` as `(y: => Unit)`. It is not a function and I do not think it is a method either. – Frank Kong Nov 22 '16 at 16:56
3
{
      println("Hello Back")
}

this is a code block, equal to:

def f = {println("Hello World")}
measure("Scala")(f)

so for measure method, you need to explicitly call:

  def measure(x: String)(y: => Unit){
   println("Hello World " + x)
   y
  }
chengpohi
  • 14,064
  • 1
  • 24
  • 42
  • Thanks for your detailed explanation – sasuke Nov 22 '16 at 02:01
  • 3
    `{}` is not a method, it's an alternative to writing `()` in this case: `scala> :k {println("a")} scala.Unit's kind is A`, also: `scala> def foo(i: Int) = i` => `scala> foo{1} res2: Int = 1`. There are multiple uses of `{}` in Scala ;). Perhaps better way to say it would be: it's a code block – yǝsʞǝla Nov 22 '16 at 02:11
  • Calling `{...}` a code block and introducing a `def` still implies that there's a difference between `measure("Scala") { println("Hello Back") }` and `measure("Scala")( println("Hello Back" )`. There isn't. What `println("Hello Back")` is, is a by-name argument. And the reason has nothing to do with the braces, but rather with the fact that `y` is declared that way. If you remove the `=>` from `y`, you can still write `measure("Scala") { println "Hello Back"}` (or `measure("Scala")(f)` if you want) and the `println` will be executed immediately. – sepp2k Nov 22 '16 at 13:34