You can call this ( => Int)
a code block which evaluates to Int only when called by name.
code: => T
is a call by name parameter
def repeat[T](code: => T)(times: Int): List[T] = {
(1 to times).toList.map {_ => code }
}
Consider the above code snippet. code
in the above function can accept any expression or group of expressions which will evaluate to T. The code block gets evaluated only when it is called by name.
Scala REPL
scala> repeat { println("hello") }(3)
hello
hello
hello
res2: List[Unit] = List((), (), ())
scala> repeat { println("hello"); 1 }(3)
hello
hello
hello
res3: List[Int] = List(1, 1, 1)
scala> repeat(println("foo"))(1)
foo
res4: List[Unit] = List(())
Call by name lets you build interesting things like loops
def loop(cond: => Boolean)(codeBlock: => Unit): Unit = {
if (cond) {
codeBlock
loop(cond)(codeBlock)
} else ()
}
Magic happens because of the lazy evaluation of the code block every time it is called by name
Scala REPL
scala> def loop(cond: => Boolean)(codeBlock: => Unit): Unit = {
| if (cond) {
| codeBlock
| loop(cond)(codeBlock)
| } else ()
| }
loop: (cond: => Boolean)(codeBlock: => Unit)Unit
scala> var i = 0
i: Int = 0
scala> loop(i < 10) { println("foobar"); i += 1}
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar