Call by name vs call by value in Scala, clarification needed
Asked Answered
M

17

257

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?

Mayan answered 12/11, 2012 at 1:33 Comment(0)
H
582

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.

Herzegovina answered 12/11, 2012 at 1:40 Comment(13)
Would it be correct to say that function declaration defines how a function will be called?Mayan
@Jam: Yes, I think that is a reasonable statement. The function declaration determines the by-value or by-name behavior.Herzegovina
I've always thought this terminology is needlessly confusing. A function can have multiple parameters which vary in their call-by-name vs call-by-value status. So it's not that a function is call-by-name or call-by-value, it's that each of its parameters may be pass-by-name or pass-by-value. Furthermore, "call-by-name" has nothing to do with names. => Int is a different type from Int; it's "function of no arguments that will generate an Int" vs just Int. Once you've got first-class functions you don't need to invent call-by-name terminology to describe this.Meld
@Ben, that helps answer a couple questions, thanks. I wish more write-ups explained the semantics of pass-by-name this clearly.Throstle
If I can add to @Meld answer, => means we are explicitly specifying a parameter to be evaluated as call by Name.Coverup
@Meld But if => Int in this case, is a function with no argument and returning an Int, then we would only be allowed to pass a function. But what we do instead is passing a value, such as f(2), with def f(x: Int) = x?Anastomosis
@Anastomosis If the text f(2) is compiled as an expression of type Int, the generated code calls f with argument 2 and the result is the value of the expression. If that same text is compiled as an expression of type => Int then the generated code uses a reference to some sort of "code block" as the value of the expression. Either way, a value of that type can be passed to a function expecting a parameter of that type. I'm pretty sure you can do this with variable assignment, with no parameter passing in sight. So what do names or calling have anything to do with it?Meld
@Meld So if => Int is "function of no arguments that generates an Int", how it that different from () => Int? Scala seems to treat these differently, for instance => Int apparently doesn't work as the type of a val, only as the type of a parameter.Cum
@TimGoodman You're right, it's a bit more complicated than I made out. => Int is a convenience, and it isn't implemented exactly as a function object is (presumably why you can't have variables of type => Int, though there's no fundamental reason why this couldn't work). () => Int is explicitly a function of no arguments that will return an Int, which needs to be called explicitly and can be passed as a function. => Int is sort of a "proxy Int", and the only thing you can do with it is call it (implicitly) to get the Int.Meld
@TimGoodman I could try and justify what I wrote a year ago by rambling about the difference between "has no arguments" and "has zero arguments" or something. But my major point was simply that the difference between the entities called x in f(x: Int) = x and f(x: => Int) = x is much more readily understood by talking about x and the way it is passed than by trying to talk about f and the way it is called (let alone about names). (And it does seem a fairly type-like property, though not entirely depending on how you look at it *shrugs*)Meld
I find the syntax in callByName(something()) a bit odd. I would have expected something like callByName(=> something()). In scheme (provided you have an appropriate function call-by-name) you would write something like: (call-by-name (lambda () (something))), i.e. you have to protect the function from invocation by putting it in a lambda. If I remember correctly, such an expression is called a thunk. Can it be that the Scala compiler constructs a thunk automatically?Hombre
@Ben, I am refering to your first comment about the naming -- pass-by-name has its merits, because it is name substitution (literally), Scala narrowed the usage of that mechanism that is why in Scala the term pass-by-name is somewhat odd.Topnotch
@Meld Passing a function with arguments is also possible "by name": def foo(x: Int): Int = { println("foo") x } def boo(x: => Int): Int = { x + x } boo(foo(2)) >> foo foo res0: Int = 4Schleswigholstein
W
55

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.

Workable answered 27/7, 2013 at 19:27 Comment(4)
In the third example for CBV, I think you meant test(7,8) instead of test(7,14)Kassab
Example is taken from Coursera, principle in scala programming. Lecture 1.2. The call by name should read def test (x:Int, y: => Int) = x * x note that the parameter y is never used.Zulmazulu
Good example! Taken from the Coursera MOOC :)Sarcophagus
This is a good explanation of the difference, but does not address to question being asked, namely which of the two is Scala callingRemarkable
U
16

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.

Ultracentrifuge answered 12/11, 2012 at 1:45 Comment(0)
A
10

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
Acciaccatura answered 30/10, 2014 at 5:42 Comment(3)
I think you meant: <!-- language: lang-scala --> def callAlsoByName(x: () => Int) = { println("x1=" + x()) println("x2=" + x()) } and then: <!-- language: lang-js --> callAlsoByName(() => something()) I don't think you need the curly braces around something() in this last call. Note: I tried to just edit your answer but my edit was rejected by reviewers saying it should be a comment or separate answer instead.Wily
Apparently you cannot use syntax highlighting in comments so just ignore the "<!-- language: lang-scala -->" part! I would have edited my own comment but you're allowed to do it only within 5 minutes! :)Wily
I recently ran into this as well. It is ok to conceptually to think it like this but scala differentiates between => T and () => T. A function that takes the first type as a parameter, will not accept the second, scala stores enough information in @ScalaSignature annotation to throw a compile time error for this. The bytecode for both => T and () => T is same though and is a Function0. See this question for more details.Crenation
C
6

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

Cordie answered 9/10, 2014 at 11:52 Comment(0)
A
4

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
Aluminothermy answered 25/2, 2016 at 11:4 Comment(0)
C
2

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.

Counseloratlaw answered 19/4, 2015 at 9:15 Comment(0)
M
2

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!

Mutualism answered 10/2, 2018 at 12:11 Comment(0)
T
2

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
========================
Tortuosity answered 27/12, 2018 at 18:0 Comment(0)
O
1

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) -> ... 
Overstuff answered 11/1, 2017 at 22:5 Comment(0)
P
1

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://mcmap.net/q/111318/-when-to-use-call-by-name-and-call-by-value

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
}
Pleo answered 13/7, 2017 at 6:5 Comment(0)
F
1

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)
 }
Frill answered 30/7, 2017 at 19:24 Comment(0)
S
1

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.

Seymour answered 28/12, 2017 at 8:54 Comment(0)
P
0

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))
Poult answered 11/9, 2015 at 6:42 Comment(0)
S
0

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.

Sybille answered 7/6, 2017 at 20:17 Comment(0)
D
-2

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.

Donohoe answered 2/8, 2016 at 11:48 Comment(0)
M
-2

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)
  }
Malacostracan answered 11/12, 2020 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.