Piotr Sobczyk Piotr Sobczyk - 3 months ago 14
Scala Question

Scala: passing function as block of code between curly braces

A few times I saw a Scala code like that:

object Doer{
def doStuff(op: => Unit) {
op
}
}


Invoked in this way:

Doer.doStuff{
println("Done")
}


What is strange for me is how function is passed to other function as just a block of code between curly braces. And there is even no parentheses that normally mark the beginning and end of argument list.

What is the name of this Scala syntax/feature? In what cases I can use it? Where is it documented?

Answer

This is called either a nullary function or a thunk, and is an example of call-by-name evaluation: http://www.scala-lang.org/old/node/138

You can use nullaries pretty much anywhere you have a parameter list. They are basically just syntactic sugar around zero-argument functions that make them look like ordinary values, and are invoked whenever they are referenced.

So

def doSomething(op: => Unit) {
  op
}
doSomething {
  println("Hello!")
}

is exactly the same as:

def doSomething(op: () => Unit) {
  op()
}
doSomething(() => println("Hello!"))

The one thing to keep in mind with nullaries is they are invoked every time they are referenced, so something like:

def foo(op: => Int) = op + op
foo {
  println("foo")
  5
}

will print "foo" twice.

Edit: To expand on Randall's comment, one of the big ways that a nullary function differs from a zero-arg function is that nullaries are not first-class values. For example, you can have a List[() => Int] but you cannot have a List[=> Int]. And if you had something like:

def foo(i: => Int) = List(i)

you are not adding the nullary function to the list, only its return value.

Comments