What does "=> Type" mean in Scala? [duplicate] - scala

As I understand it, in Scala, a function may be called either
by-value or
by-name
For example, given the following declarations, do we know how the function will be called?
Declaration:
def f (x:Int, y:Int) = x;
Call
f (1,2)
f (23+55,5)
f (12+3, 44*11)
What are the rules please?

The example you have given only uses call-by-value, so I will give a new, simpler, example that shows the difference.
First, let's assume we have a function with a side-effect. This function prints something out and then returns an Int.
def something() = {
println("calling something")
1 // return value
}
Now we are going to define two function that accept Int arguments that are exactly the same except that one takes the argument in a call-by-value style (x: Int) and the other in a call-by-name style (x: => Int).
def callByValue(x: Int) = {
println("x1=" + x)
println("x2=" + x)
}
def callByName(x: => Int) = {
println("x1=" + x)
println("x2=" + x)
}
Now what happens when we call them with our side-effecting function?
scala> callByValue(something())
calling something
x1=1
x2=1
scala> callByName(something())
calling something
x1=1
calling something
x2=1
So you can see that in the call-by-value version, the side-effect of the passed-in function call (something()) only happened once. However, in the call-by-name version, the side-effect happened twice.
This is because call-by-value functions compute the passed-in expression's value before calling the function, thus the same value is accessed every time. Instead, call-by-name functions recompute the passed-in expression's value every time it is accessed.

Here is an example from Martin Odersky:
def test (x:Int, y: Int)= x*x
We want to examine the evaluation strategy and determine which one is faster (less steps) in these conditions:
test (2,3)
call by value: test(2,3) -> 2*2 -> 4
call by name: test(2,3) -> 2*2 -> 4
Here the result is reached with the same number of steps.
test (3+4,8)
call by value: test (7,8) -> 7*7 -> 49
call by name: (3+4) (3+4) -> 7(3+4)-> 7*7 ->49
Here call by value is faster.
test (7,2*4)
call by value: test(7,8) -> 7*7 -> 49
call by name: 7 * 7 -> 49
Here call by name is faster
test (3+4, 2*4)
call by value: test(7,2*4) -> test(7, 8) -> 7*7 -> 49
call by name: (3+4)(3+4) -> 7(3+4) -> 7*7 -> 49
The result is reached within the same steps.

In the case of your example all the parameters will be evaluated before it's called in the function , as you're only defining them by value.
If you want to define your parameters by name you should pass a code block:
def f(x: => Int, y:Int) = x
This way the parameter x will not be evaluated until it's called in the function.
This little post here explains this nicely too.

To iteratate #Ben's point in the above comments, I think it's best to think of "call-by-name" as just syntactic sugar. The parser just wraps the expressions in anonymous functions, so that they can be called at a later point, when they are used.
In effect, instead of defining
def callByName(x: => Int) = {
println("x1=" + x)
println("x2=" + x)
}
and running:
scala> callByName(something())
calling something
x1=1
calling something
x2=1
You could also write:
def callAlsoByName(x: () => Int) = {
println("x1=" + x())
println("x2=" + x())
}
And run it as follows for the same effect:
callAlsoByName(() => {something()})
calling something
x1=1
calling something
x2=1

I will try to explain by a simple use case rather than by just providing an example
Imagine you want to build a "nagger app" that will Nag you every time since time last you got nagged.
Examine the following implementations:
object main {
def main(args: Array[String]) {
def onTime(time: Long) {
while(time != time) println("Time to Nag!")
println("no nags for you!")
}
def onRealtime(time: => Long) {
while(time != time) println("Realtime Nagging executed!")
}
onTime(System.nanoTime())
onRealtime(System.nanoTime())
}
}
In the above implementation the nagger will work only when passing by name
the reason is that, when passing by value it will re-used and therefore the value will not be re-evaluated while when passing by name the value will be re-evaluated every time the variables is accessed

Typically, parameters to functions are by-value parameters; that is, the value of the parameter is determined before it is passed to the function. But what if we need to write a function that accepts as a parameter an expression that we don't want evaluated until it's called within our function? For this circumstance, Scala offers call-by-name parameters.
A call-by-name mechanism passes a code block to the callee and each time the callee accesses the parameter, the code block is executed and the value is calculated.
object Test {
def main(args: Array[String]) {
delayed(time());
}
def time() = {
println("Getting time in nano seconds")
System.nanoTime
}
def delayed( t: => Long ) = {
println("In delayed method")
println("Param: " + t)
t
}
}
1. C:/>scalac Test.scala
2. scala Test
3. In delayed method
4. Getting time in nano seconds
5. Param: 81303808765843
6. Getting time in nano seconds

As i assume, the call-by-value function as discuss above pass just the values to the function. According to Martin Odersky It is a Evaluation strategy follow by a Scala that play the important role in function evaluation. But, Make it simple to call-by-name. its like a pass the function as a argument to the method also know as Higher-Order-Functions. When the method access the value of passed parameter, it call the implementation of passed functions. as Below:
According to #dhg example, create the method first as:
def something() = {
println("calling something")
1 // return value
}
This function contain one println statement and return an integer value. Create the function, who have arguments as a call-by-name:
def callByName(x: => Int) = {
println("x1=" + x)
println("x2=" + x)
}
This function parameter, is define an anonymous function who have return one integer value. In this x contain an definition of function who have 0 passed arguments but return int value and our something function contain same signature. When we call the function, we pass the function as a argument to callByName. But in the case of call-by-value its only pass the integer value to the function. We call the function as below:
scala> callByName(something())
calling something
x1=1
calling something
x2=1
In this our something method called twice, because when we access the value of x in callByName method, its call to the defintion of something method.

Call by value is general use case as explained by many answers here..
Call-by-name passes a code block to the caller and each time the
caller accesses the parameter, the code block is executed and the
value is calculated.
I will try to demonstrate call by name more simple way with use cases below
Example 1:
Simple example/use case of call by name is below function, which takes function as parameter and gives the time elapsed.
/**
* Executes some code block and prints to stdout the
time taken to execute the block
for interactive testing and debugging.
*/
def time[T](f: => T): T = {
val start = System.nanoTime()
val ret = f
val end = System.nanoTime()
println(s"Time taken: ${(end - start) / 1000 / 1000} ms")
ret
}
Example 2:
apache spark (with scala) uses logging using call by name way see Logging trait
in which its lazily evaluates whether log.isInfoEnabled or not from the below method.
protected def logInfo(msg: => String) {
if (log.isInfoEnabled) log.info(msg)
}

In a Call by Value, the value of the expression is pre-computed at the time of the function call and that particular value is passed as the parameter to the corresponding function. The same value will be used all throughout the function.
Whereas in a Call by Name, the expression itself is passed as a parameter to the function and it is only computed inside the function, whenever that particular parameter is called.
The difference between Call by Name and Call by Value in Scala could be better understood with the below example:
Code Snippet
object CallbyExample extends App {
// function definition of call by value
def CallbyValue(x: Long): Unit = {
println("The current system time via CBV: " + x);
println("The current system time via CBV " + x);
}
// function definition of call by name
def CallbyName(x: => Long): Unit = {
println("The current system time via CBN: " + x);
println("The current system time via CBN: " + x);
}
// function call
CallbyValue(System.nanoTime());
println("\n")
CallbyName(System.nanoTime());
}
Output
The current system time via CBV: 1153969332591521
The current system time via CBV 1153969332591521
The current system time via CBN: 1153969336749571
The current system time via CBN: 1153969336856589
In the above code snippet, for the function call CallbyValue(System.nanoTime()), the system nano time is pre-calculated and that pre-calculated value has been passed a parameter to the function call.
But in the CallbyName(System.nanoTime()) function call, the expression "System.nanoTime())" itself is passed as a parameter to the function call and the value of that expression is calculated when that parameter is used inside the function.
Notice the function definition of the CallbyName function, where there is a => symbol separating the parameter x and its datatype. That particular symbol there indicates the function is of call by name type.
In other words, the call by value function arguments are evaluated once before entering the function, but the call by name function arguments are evaluated inside the function only when they are needed.
Hope this helps!

Here is a quick example I coded to help a colleague of mine who is currently taking the Scala course. What I thought was interesting is that Martin didn't use the && question answer presented earlier in the lecture as an example. In any event I hope this helps.
val start = Instant.now().toEpochMilli
val calc = (x: Boolean) => {
Thread.sleep(3000)
x
}
def callByValue(x: Boolean, y: Boolean): Boolean = {
if (!x) x else y
}
def callByName(x: Boolean, y: => Boolean): Boolean = {
if (!x) x else y
}
new Thread(() => {
println("========================")
println("Call by Value " + callByValue(false, calc(true)))
println("Time " + (Instant.now().toEpochMilli - start) + "ms")
println("========================")
}).start()
new Thread(() => {
println("========================")
println("Call by Name " + callByName(false, calc(true)))
println("Time " + (Instant.now().toEpochMilli - start) + "ms")
println("========================")
}).start()
Thread.sleep(5000)
The output of the code will be the following:
========================
Call by Name false
Time 64ms
========================
Call by Value false
Time 3068ms
========================

Parameters are usually pass by value, which means that they'll be evaluated before being substituted in the function body.
You can force a parameter to be call by name by using the double arrow when defining the function.
// first parameter will be call by value, second call by name, using `=>`
def returnOne(x: Int, y: => Int): Int = 1
// to demonstrate the benefits of call by name, create an infinite recursion
def loop(x: Int): Int = loop(x)
// will return one, since `loop(2)` is passed by name so no evaluated
returnOne(2, loop(2))
// will not terminate, since loop(2) will evaluate.
returnOne(loop(2), 2) // -> returnOne(loop(2), 2) -> returnOne(loop(2), 2) -> ...

There are already lots of fantastic answers for this question in Internet. I will write a compilation of several explanations and examples I have gathered about the topic, just in case someone may find it helpful
INTRODUCTION
call-by-value (CBV)
Typically, parameters to functions are call-by-value parameters; that is, the parameters are evaluated left to right to determine their value before the function itself is evaluated
def first(a: Int, b: Int): Int = a
first(3 + 4, 5 + 6) // will be reduced to first(7, 5 + 6), then first(7, 11), and then 7
call-by-name (CBN)
But what if we need to write a function that accepts as a parameter an expression that we don't to evaluate until it's called within our function? For this circumstance, Scala offers call-by-name parameters. Meaning the parameter is passed into the function as it is, and its valuation takes place after substitution
def first1(a: Int, b: => Int): Int = a
first1(3 + 4, 5 + 6) // will be reduced to (3 + 4) and then to 7
A call-by-name mechanism passes a code block to the call and each time the call accesses the parameter, the code block is executed and the value is calculated. In the following example, delayed prints a message demonstrating that the method has been entered. Next, delayed prints a message with its value. Finally, delayed returns ‘t’:
object Demo {
def main(args: Array[String]) {
delayed(time());
}
def time() = {
println("Getting time in nano seconds")
System.nanoTime
}
def delayed( t: => Long ) = {
println("In delayed method")
println("Param: " + t)
}
}
In delayed method
Getting time in nano seconds
Param: 2027245119786400
PROS AND CONS FOR EACH CASE
CBN:
+Terminates more often * check below above termination *
+ Has the advantage that a function argument is not evaluated if the corresponding parameter is unused in the evaluation of the function body
-It is slower, it creates more classes (meaning the program takes longer to load) and it consumes more memory.
CBV:
+ It is often exponentially more efficient than CBN, because it avoids this repeated recomputation of arguments expressions that call by name entails. It evaluates every function argument only once
+ It plays much nicer with imperative effects and side effects, because you tend to know much better when expressions will be evaluated.
-It may lead to a loop during its parameters evaluation * check below above termination *
What if termination is not guaranteed?
-If CBV evaluation of an expression e terminates, then CBN evaluation of e terminates too
-The other direction is not true
Non-termination example
def first(x:Int, y:Int)=x
Consider the expression first(1,loop)
CBN: first(1,loop) → 1
CBV: first(1,loop) → reduce arguments of this expression. Since one is a loop, it reduce arguments infinivly. It doesn’t terminate
DIFFERENCES IN EACH CASE BEHAVIOUR
Let's define a method test that will be
Def test(x:Int, y:Int) = x * x //for call-by-value
Def test(x: => Int, y: => Int) = x * x //for call-by-name
Case1 test(2,3)
test(2,3) → 2*2 → 4
Since we start with already evaluated arguments it will be the same amount of steps for call-by-value and call-by-name
Case2 test(3+4,8)
call-by-value: test(3+4,8) → test(7,8) → 7 * 7 → 49
call-by-name: (3+4)*(3+4) → 7 * (3+4) → 7 * 7 → 49
In this case call-by-value performs less steps
Case3 test(7, 2*4)
call-by-value: test(7, 2*4) → test(7,8) → 7 * 7 → 49
call-by-name: (7)*(7) → 49
We avoid the unnecessary computation of the second argument
Case4 test(3+4, 2*4)
call-by-value: test(7, 2*4) → test(7,8) → 7 * 7 → 49
call-by-name: (3+4)*(3+4) → 7*(3+4) → 7*7 → 49
Different approach
First, let's assume we have a function with a side-effect. This function prints something out and then returns an Int.
def something() = {
println("calling something")
1 // return value
}
Now we are going to define two function that accept Int arguments that are exactly the same except that one takes the argument in a call-by-value style (x: Int) and the other in a call-by-name style (x: => Int).
def callByValue(x: Int) = {
println("x1=" + x)
println("x2=" + x)
}
def callByName(x: => Int) = {
println("x1=" + x)
println("x2=" + x)
}
Now what happens when we call them with our side-effecting function?
scala> callByValue(something())
calling something
x1=1
x2=1
scala> callByName(something())
calling something
x1=1
calling something
x2=1
So you can see that in the call-by-value version, the side-effect of the passed-in function call (something()) only happened once. However, in the call-by-name version, the side-effect happened twice.
This is because call-by-value functions compute the passed-in expression's value before calling the function, thus the same value is accessed every time. However, call-by-name functions recompute the passed-in expression's value every time it is accessed.
EXAMPLES WHERE IT IS BETTER TO USE CALL-BY-NAME
From: https://stackoverflow.com/a/19036068/1773841
Simple performance example: logging.
Let's imagine an interface like this:
trait Logger {
def info(msg: => String)
def warn(msg: => String)
def error(msg: => String)
}
And then used like this:
logger.info("Time spent on X: " + computeTimeSpent)
If the info method doesn't do anything (because, say, the logging level was configured for higher than that), then computeTimeSpent never gets called, saving time. This happens a lot with loggers, where one often sees string manipulation which can be expensive relative to the tasks being logged.
Correctness example: logic operators.
You have probably seen code like this:
if (ref != null && ref.isSomething)
Imagine you would declare && method like this:
trait Boolean {
def &&(other: Boolean): Boolean
}
then, whenever ref is null, you'll get an error because isSomething will be called on a nullreference before being passed to &&. For this reason, the actual declaration is:
trait Boolean {
def &&(other: => Boolean): Boolean =
if (this) this else other
}

Going through an example should help you better understand the difference.
Let's definie a simple function that returns the current time:
def getTime = System.currentTimeMillis
Now we'll define a function, by name, that prints two times delayed by a second:
def getTimeByName(f: => Long) = { println(f); Thread.sleep(1000); println(f)}
And a one by value:
def getTimeByValue(f: Long) = { println(f); Thread.sleep(1000); println(f)}
Now let's call each:
getTimeByName(getTime)
// prints:
// 1514451008323
// 1514451009325
getTimeByValue(getTime)
// prints:
// 1514451024846
// 1514451024846
The result should explain the difference. The snippet is available here.

CallByName is invoked when used and callByValue is invoked whenever the statement is encountered.
For example:-
I have a infinite loop i.e. if you execute this function we will never get scala prompt.
scala> def loop(x:Int) :Int = loop(x-1)
loop: (x: Int)Int
a callByName function takes above loop method as an argument and it is never used inside its body.
scala> def callByName(x:Int,y: => Int)=x
callByName: (x: Int, y: => Int)Int
On execution of callByName method we don't find any problem ( we get scala prompt back ) as we are no where using the loop function inside callByName function.
scala> callByName(1,loop(10))
res1: Int = 1
scala>
a callByValue function takes above loop method as a parameter as a result inside function or expression is evaluated before executing outer function there by loop function executed recursively and we never get scala prompt back.
scala> def callByValue(x:Int,y:Int) = x
callByValue: (x: Int, y: Int)Int
scala> callByValue(1,loop(1))

See this:
object NameVsVal extends App {
def mul(x: Int, y: => Int) : Int = {
println("mul")
x * y
}
def add(x: Int, y: Int): Int = {
println("add")
x + y
}
println(mul(3, add(2, 1)))
}
y: => Int is call by name. What is passed as call by name is add(2, 1). This will be evaluated lazily. So output on console will be "mul" followed by "add", although add seems to be called first. Call by name acts as kind of passing a function pointer.
Now change from y: => Int to y: Int. Console will show "add" followed by "mul"! Usual way of evaluation.

I don't think all the answers here do the correct justification:
In call by value the arguments are computed just once:
def f(x : Int, y :Int) = x
// following the substitution model
f(12 + 3, 4 * 11)
f(15, 4194304)
15
you can see above that all the arguments are evaluated whether needed are not, normally call-by-value can be fast but not always like in this case.
If the evaluation strategy was call-by-name then the decomposition would have been:
f(12 + 3, 4 * 11)
12 + 3
15
as you can see above we never needed to evaluate 4 * 11 and hence saved a bit of computation which may be beneficial sometimes.

Scala variable evaluation explained here in better https://sudarshankasar.medium.com/evaluation-rules-in-scala-1ed988776ae8
def main(args: Array[String]): Unit = {
//valVarDeclaration 2
println("****starting the app***") // ****starting the app***
val defVarDeclarationCall1 = defVarDeclaration // defVarDeclaration 1
val defVarDeclarationCall2 = defVarDeclaration // defVarDeclaration 1
val valVarDeclarationCall1 = valVarDeclaration //
val valVarDeclarationCall2 = valVarDeclaration //
val lazyValVarDeclarationCall1 = lazyValVarDeclaration // lazyValVarDeclaration 3
val lazyValVarDeclarationCall2 = lazyValVarDeclaration //
callByValue({
println("passing the value "+ 10)
10
}) // passing the value 10
// call by value example
// 10
callByName({
println("passing the value "+ 20)
20
}) // call by name example
// passing the value 20
// 20
}
def defVarDeclaration = {
println("defVarDeclaration " + 1)
1
}
val valVarDeclaration = {
println("valVarDeclaration " + 2)
2
}
lazy val lazyValVarDeclaration = {
println("lazyValVarDeclaration " + 3)
3
}
def callByValue(x: Int): Unit = {
println("call by value example ")
println(x)
}
def callByName(x: => Int): Unit = {
println("call by name example ")
println(x)
}

Related

Why does scala call the method passed to println before printing the line it is called in?

The program looks like this ...
object Delay{
def main(args: Array[String]){
delayed(time())
}
def time()={
println("Getting time in nanoseconds : ")
System.nanoTime
}
def delayed(t: => Long)={
println("In delayed Method")
println("Param : "+t)
}
}
And the output is ...
In delayed Method
Getting time in nanoseconds :
Param : 139735036142049
My question is why does the word "Param :" print after the "Getting time ..." and not like,
In delayed Method
Param :
Getting time in nanoseconds : 139735036142049
The reason why you see this execution order, is because t is a by-name parameter in your code:
def delayed(t: => Long)
If you defined your delayed method with a by-value parameter like so:
def delayed(t: Long)
the time() function would have been evaluated before the call to delayed, and you would get the following output instead:
Getting time in nanoseconds :
In delayed Method
Param : 139735036142049
The trick is that by-name parameters are called only when they're used, and every time they're used. From the Scala docs:
By-name parameters are only evaluated when used. They are in contrast to by-value parameters.
By-name parameters have the advantage that they are not evaluated if they aren’t used in the function body. On the other hand, by-value parameters have the advantage that they are evaluated only once.
t/time value will be evaluated before printing param.
so it prints println("Getting time in nanoseconds:")
before printing println("Param : "+t)
IMHO the current scala doc, within the link provided by Zoltan, is misleading and confusing. By-name parameters have the advantage of repetitive read / call / evaluation, and are used mainly for that purpose. The delayed evaluation has to do with lazy vals, that is a different topic. The delayed evaluation of by-name, when passed as var / closure / anonymous_function, is just a collateral effect of the repetitiveness - given as an example, in the same scala doc, under the from of a whileLoop example.
By-name parameter behavior depends on what you pass as actual param -
if you pass a val(ue)/constant it will be evaluated in advance,
if you pass a var its value will be read each time the by-name is
referenced by the runtime code
if you pass a closure / anonymous_function it will get called each
time the by-name is referenced by the runtime code
.
def two[A](a: => A): List[A] = List(a, a) // two references
def two_iter[A](a: => A) { (1 to 2) foreach { x => a } } // two references
def two_lazy[A](a: => A) = { lazy val b = a; List(b, b) // one lazy reference
def two_delayed[A](a: => A): List[A] = { val l = List(a); Thread.sleep(5000); a :: l } // two references with delay
val x = 5; two(5); two(x) // (5, 5) only once
var z = 5; val f = Future { two_delayed(z) }; Thread.sleep(1000); z += 1; f.onSuccess { case result => println(result) } // (6, 5) two reads
two { println("in"); 5 } // (5, 5) called twice
var t = 0; two { println("in"); t += 1; t } // (1, 2) called twice
two_iter { println("in"); 5 } // called twice
two_lazy { println("in"); 5 } // (5, 5) called once

What is the order of printing in scala println() when there is a function call inside println()? [duplicate]

The program looks like this ...
object Delay{
def main(args: Array[String]){
delayed(time())
}
def time()={
println("Getting time in nanoseconds : ")
System.nanoTime
}
def delayed(t: => Long)={
println("In delayed Method")
println("Param : "+t)
}
}
And the output is ...
In delayed Method
Getting time in nanoseconds :
Param : 139735036142049
My question is why does the word "Param :" print after the "Getting time ..." and not like,
In delayed Method
Param :
Getting time in nanoseconds : 139735036142049
The reason why you see this execution order, is because t is a by-name parameter in your code:
def delayed(t: => Long)
If you defined your delayed method with a by-value parameter like so:
def delayed(t: Long)
the time() function would have been evaluated before the call to delayed, and you would get the following output instead:
Getting time in nanoseconds :
In delayed Method
Param : 139735036142049
The trick is that by-name parameters are called only when they're used, and every time they're used. From the Scala docs:
By-name parameters are only evaluated when used. They are in contrast to by-value parameters.
By-name parameters have the advantage that they are not evaluated if they aren’t used in the function body. On the other hand, by-value parameters have the advantage that they are evaluated only once.
t/time value will be evaluated before printing param.
so it prints println("Getting time in nanoseconds:")
before printing println("Param : "+t)
IMHO the current scala doc, within the link provided by Zoltan, is misleading and confusing. By-name parameters have the advantage of repetitive read / call / evaluation, and are used mainly for that purpose. The delayed evaluation has to do with lazy vals, that is a different topic. The delayed evaluation of by-name, when passed as var / closure / anonymous_function, is just a collateral effect of the repetitiveness - given as an example, in the same scala doc, under the from of a whileLoop example.
By-name parameter behavior depends on what you pass as actual param -
if you pass a val(ue)/constant it will be evaluated in advance,
if you pass a var its value will be read each time the by-name is
referenced by the runtime code
if you pass a closure / anonymous_function it will get called each
time the by-name is referenced by the runtime code
.
def two[A](a: => A): List[A] = List(a, a) // two references
def two_iter[A](a: => A) { (1 to 2) foreach { x => a } } // two references
def two_lazy[A](a: => A) = { lazy val b = a; List(b, b) // one lazy reference
def two_delayed[A](a: => A): List[A] = { val l = List(a); Thread.sleep(5000); a :: l } // two references with delay
val x = 5; two(5); two(x) // (5, 5) only once
var z = 5; val f = Future { two_delayed(z) }; Thread.sleep(1000); z += 1; f.onSuccess { case result => println(result) } // (6, 5) two reads
two { println("in"); 5 } // (5, 5) called twice
var t = 0; two { println("in"); t += 1; t } // (1, 2) called twice
two_iter { println("in"); 5 } // called twice
two_lazy { println("in"); 5 } // (5, 5) called once

what is the difference between passing parameters () => T and just T

specifically, what is the difference for following two definitions:
def func(f: () => String) = f()
def func1(s: String) = s
I wrote some codes to test them, it seems they produce the same result; are those two definitions just the same in this scenario; or they do have some difference?
var x = 1
def f() = {
x = x + 1
s"$x"
}
println(func1(f))
println(func1(f))
println(func1(f))
println(func(f))
println(func(f))
println(func(f))
They are perhaps the same in THIS scenario, but there are lots of other scenarios when a () => A and a A are much different. () => A is referred to as a thunk and is used to pass a piece of delayed computation to a function. The body of the "thunk" doesn't get evaluated until the function called decides to evaluate it. Otherwitse, the value of the argument being passed in is evaluated by the caller.
Consider this example, where there IS a difference between the version that takes a thunk and the version that just takes a value:
object Thunk {
def withThunk(f: () ⇒ String): Unit = {
println("withThunk before")
println("the thunk's value is: " + f())
println("now the thunk's value is: " + f())
}
def withoutThunk(f: String): Unit = {
println("withoutThunk before")
println("now the value's value is: " + f)
}
def main(argv: Array[String]): Unit = {
withThunk { () ⇒ println("i'm inside a thunk"); "thunk value" }
println("------------")
withoutThunk { println("i'm not inside a thunk"); "just a value" }
}
}
This program will demonstrate some differences. In the thunk version, you see "withThunk before" get printed before the first time "i'm inside a thunk" gets printed, which gets printed twice, since f() is evaluated twice. In the non-thunk version, the "I'm not inside a thunk" gets printed before "withoutThunk before", since this is evaluated before being sent to the function as an argument.
def func(f: () => String) = f()
This one accepts as parameter a function that returns a string.
def func1(s: String) = s
While this one simple requires a String as parameter
Aside from the minor technical difference above, in this scenario they seem to function the same. However, the function parameter is potentially more powerful as it is a function that can derive its return value from several other operations. I think however, the main difference that the function parameter allows you to decide when the value is derived.
def func(f: () => String) = f()
def func1(s: String) = s
println(func1(f)) // in this case f is evaluated first, its value is used in func1.
println(func(f)) // in this case f is NOT evaluated, but passed as it is to func.
// It is upto func to call f whenever needed, or even not call it.
It is this "lazy" evaluation of f, that makes func more useful, for instance f can be passed to some other higher order functions, or it can be called asynchronously.
I want to add an example for the use of () => String.
def printFuncResult(f: () => String) = println(f() + " " + f())
def ran = () => Math.random.toString
printFuncResult(ran)
printFuncResult(Math.random.toString)
When you pass a function like ran then you will most likely have two different values printed (randomness is involved here). When you pass a fixed Random number then it will be printed twice.
As you can see: when you have a function as a parameter it might result in a different value each time it is used in printFuncResult. This is not possible when you just put a String parameter.

scala. higher order function calling by name. does it make sense

Just want to clarify. If we use higher-order function (f. that accepts another function as argument). Does it make any sense specify "=>" sign to call it by-name. It seems arg-function is calling by-name anyhow?
There is an example:
// 1.
// the function that accepts arg-function with: two int params and returning String
// the function passing v1 & v2 as parameters to arg-function, invoking arg-function 2 times, connecting the result to one string
def takeFunction1(f: (Int, Int) => String, v1:Int, v2:Int ): String = {
f(v1, v2) + f(v1, v2)
}
// 2. same as #1 but calling arg-function by-name
def takeFunction2(f: => ((Int, Int) => String), v1:Int, v2:Int ): String = {
f(v1, v2) + f(v1, v2)
}
def aFun(v1:Int, v2:Int) : String = {
(v1 + v2).toString
}
// --
println( takeFunction1( aFun, 2, 2) )
println( takeFunction2( aFun, 2, 2) )
And what if I want to call it like this ?:
println( takeFunction2( aFun(2,2)), ... ) // it tries to evaluate immediately when passing
The difference is that if you pass as the first argument a call to a function that returns the (Int, Int) => String value to use, this call to the generator function is evaluated only once with pass-by-value, compared to being evaluated each time the argument is used in the case of pass-by-name.
Rather contrived example:
var bar = 0
def fnGen() = {
bar += 1
def myFun(v1:Int, v2:Int) = {
(v1 + v2).toString
}
myFun _
}
Now run some calls of your methods above using fnGen:
scala> println( takeFunction1( fnGen(), 2, 2) )
44
scala> bar
res1: Int = 1
scala> println( takeFunction2( fnGen(), 2, 2) )
44
scala> bar
res3: Int = 3
As you can see, calling takeFunction1 increments bar only once, while calling takeFunction2 increments bar twice.
The argument that you're passing by name is aFun; that's a valid expression, and it does get evaluated both times that takeFunction2 uses it, but since it's just a variable, and you're not doing anything else with it, "evaluating" it is not very meaningful. (It just evaluates to the same value both times.) For pass-by-name to behave differently from pass-by-value, you have to pass in an impure expression (one that has side-effects, or that can evaluate to different values on successive calls, or whatnot).

What does "code: => Unit" mean in scala?

Does anyone know the type of => Unit in scala? I don't know the meaning of => Unit and how to use it. I defined a function like below:
def test(code: => Unit){
print("start ...")
code
print("end ....")
}
test(print(1))
Does it means a function with any arguments returning Unit?
Thanks
This kind of parameter are called by-name parameter
=> B represents a block a of code which return a B value, their purpose is that they are evaluated only when you call the parameter.
def foo(code: => Int) {
println("Not yet evaluated")
val result = code
println("parameter evaluated %s, is it an int ? %s " format (
result, result.isInstanceOf[Int]) )
}
And you can call foo in the following way :
foo(1)
or
val a = 3
val b = 5
foo {
val c = a * a
c * b
}
The other style of passing parameter is by-value : parameters are evaluated before they are sent to the method
def foo(code : Int) {
println("Parameter already evaluated")
val result = code
println("parameter evaluated : " + result)
}
References
Extract from the Book Functionnal Programming in Scala
More differences between by-name parameter and by-value parameter illustrated
In x: => Type the x is a call by name parameter. That's different than taking an argument which is a function taking no arguments: x: () => Type
This is called a by name parameter, as related to call-by-name parameter evaluation strategy. Please see the linked wikipedia article for similar, but not identical, ways of passing parameters.
To explain it better, let's consider first the two most common parameter evaluation strategies: call by value and call by reference.
Call by value is by far the most common evaluation strategy. It is the sole strategy in Java, for instance, and the default strategy in C. Consider, for instance, this simple Java program:
public class ByValue {
static public void inc(int y) {
y++;
}
static public void main(String... args) {
int x = 0;
inc(x);
System.out.println(x);
}
}
It will print 0, because x's value is copied to y, so that when y is incremented it doesn't change the original value in x. Contrast this with this C++ program with call-by-reference:
#include <stdio.h>
void inc(int &y) {
y++;
}
int main() {
int x = 0;
inc(x);
printf("%d\n", x);
}
This will print 1, because the reference to x is passed to inc, instead of x's value.
Note that Java passes objects references by value, which leads some to claim it does call by reference. This is not true, to the extent that if you were to assign a new object to a parameter of a function, it would not be reflected in the function's caller.
So, what does a call by name looks like? In a call by name, neither value nor reference is passed. Instead, the whole code is passed, and everywhere the parameter is used, the code is executed and its result used. For example:
object ByName {
def incIfZero(y: => Int): Int = if (y == 0) y + 1 else y
def main(args: Array[String]) {
var x = 0
x = incIfZero( { val tmp = x; x += 1; tmp } )
println(x)
}
}
This example prints 2 instead of 1, because the block of code passed as parameter is evaluted twice. When executing, it's as if the second line in the main was written like this:
x = if ({ val tmp = x; x += 1; tmp }) { val tmp = x; x += 1; tmp } + 1 else { val tmp = x; x += 1; tmp }
Now, by name parameters have at least three interesting uses:
It can be used to delay the execution of something until the proper time.
It can be used to avoid the execution in some situations.
It can be used to execute some block of code multiple times.
The first and last cases are pretty obvious, I think. Here's an example of the second case:
implicit def fromBoolean(b: Boolean) = new {
def and(that: => Boolean): Boolean = if (b) that else b }
val x = 0
(x > 0) and (10 / x > 0)
If that was not a by name parameter, there would be an exception thrown at the last line. As it is, it will just return false.
It means call-by-name, which basically means that the value is calculated when used in your function. As opposed to call-by-value which is default in Java (and Scala with regular type syntax), where the value is calculated before the method is called. A Unit type would not make much sense in call-by-value I guess..
This is typically used to create functions that behave as custom control structures, or things like timing or logging as in your example. Stuff you often use AOP to do in Java.