Call-by-name and Call-by-value in Scala

Source: Internet
Author: User
Tags function definition
Call-by-name and Call-by-value in Scala Var/def/val/lazy Valdef: Similar to every assignment, if you define a function with Def, you regain a function each time, doing call-by-name operations. Val: Get once and execute immediately, and no longer be modified during the life cycle, using the call-by-value operation. var: can be assigned again in the lifecycle lazy Val: Lazy execution, which is assignment (binding), is not performed until it is needed Example
scala> def f = {println ("hello"); 1.0}
f:double

scala> f
Hello
res3:double = 1.0

scala> f< C8/>hello
res4:double = 1.0

scala> f
Hello
res5:double = 1.0

This uses Def, which is equivalent to getting a new function each time it is used.
The embodiment is that every time you use F, you get a {println ("hello"); 1.0} with a return value of 1, but the middle process prints out Hello, which is printed when the assignment (binding) occurs.

Scala> val f = {println ("hello"); 1.0}
Hello
f:double = 1.0 scala>

f
res6:double = 1.0

S cala> F
res7:double = 1.0

Using Val here, there is only one binding, so Hello is no longer printed later. If you feel confused, you can continue to watch.

Scala> lazy val f = {println ("hello"); 1.0}
f:double = <lazy>

scala> f
Hello
res8:double = 1.0

scala> F
res9:double = 1.0

The lazy Val is used here, which is the lazy evaluation. You can see that when you do the binding, you don't print hello and you don't see its value, because you just define this value.

When used for the second time, the value is actually computed (similar to Val), the first time the Hello is printed, and then the Call-by-name and call-by-value in the function definition are no longer printed.

Read the above explanation still feel confused, is not quite understand call-by-name and call-by-value.

The biggest difference between Scala call by name and call by value is:

Call-by-name will recalculate by name at the time of the call, and call-by-value the calculation, and then keep the computed value for the use of this value. Pure Function Example [1]

An example of a stack overflow.

def something () = {
  println ("Calling Something")
  1//return value
}

def callbyvalue (x:int) = {
  Prin  TLN ("x1=" + x)
  println ("x2=" + x)
}

def callByName (x: => Int) = {
  println ("x1=" + x)
  println ("x2=" + x)
}

scala> Callbyvalue (Something ())
calling something
x1=1
x2=1

CallByName (Something ())
calling something
x1=1
calling something
x2=1

This is because before the function is invoked, Call-by-value evaluates the value of the passed-in expression, so each time the same value is accessed and is not called again.

However, Call-by-name, the value of the passed-in expression is recalculated each time it is applied. examples of impure functions [2]

are pure functions, it may be more obvious to write a non pure function below.

For example, suppose an alcoholic, who initially had 10 yuan, would spend a dollar a day drinking. Set him up with a skill that counts his own money and returns the latest number of money in his pocket every day.

Object Drunkard {
    //start with the soft sister currency  
    var money = ten

    //every day to drink a soft sister currency  
    def drink:unit = {money-
        = 1
    }

    //number The money to be drunk on the soft sister currency  
    def count:int = {
        drink

    Money}//Every day a few dollars  
    def printbyname (x: => Int): unit = {
        for (i <-0 until 5)
            println ("Counted every day, the drunkard left" + x + "dollars.") ")
    }

    //First days on the wall, after every day to see the balance of the wall  
    def printbyvalue (x:int): unit = {for
        (I <-0 until 5)
            println ( "Only the first day, the drunkard left" + x + "block money. '
    }

    def main (args:array[string]) = {
        Printbyname (count)
        Printbyvalue (count)
    }
}
* *
every day, the drunkard has 9 dollars left.  
every day, an alcoholic has 8 dollars left.  
every day, an alcoholic has 7 dollars left.  
every day, an alcoholic has 6 dollars left.  
every day, an alcoholic has 5 dollars left.  
only on the first day, the drunkard had 4 dollars left.  
only on the first day, the drunkard had 4 dollars left.  
only on the first day, the drunkard had 4 dollars left.  
only on the first day, the drunkard had 4 dollars left.  
only on the first day, the drunkard had 4 dollars left.
*/  

As you can see, the first 5 days a drunkard will count the soft sister coins in her pocket every day (Call-by-name), and get the number of soft sister coins left after drinking and spending every day.

He felt the trouble, and came up with a clever way, on the sixth day, he put the remaining balance in his pocket on the Wall (Call-by-value), and later every day to see the number on the wall, they know how much money they have left. Death Cycle Example

We can write a recursive "loop" of functions.

If it stops under the call-by-name, it does not mean that it will stop under Call-by-value.
However, if the call-by-value stopped, Call-by-name would surely stop.

This is a dead loop
 def Loop:boolean = loop

 //Call-by-value when defined with Val, the following statement blocks
 val x = Loop 

 //DEF definition, is to do the call-by-name. Therefore, the following statement will not be executed for the time being, when Y is used to do evaluation
 def y = loop
The comparison between the two

The call-by-value evaluates the parameter expression before entering the function body, which avoids the repeated calculation of the value of the parameter within the function and improves the efficiency to some extent.

But one advantage of call-by-name is that if the parameter is not used inside the function body, then it does not have to compute the value of the parameter expression. In this case, the efficiency of the call-by-name will be a little higher.

Object Main {

    def useornotuse (Flag:boolean, X:int, y: => Int) = {
        if (flag) {
            x
        }
        else {
            x + Y
        }

    def main (args:array[string]) = {
        Val flag = True
        println (Useornotuse (flag, 1, 2))
        Val Flag = False
        println (Useornotuse (flag, 1, 2))
    }
}  
reference materialsCall by name vs. call by value in Scala, clarification needed Scala var,val,immutable,mutable understanding summary Scala Call-by-name and call -by-value

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.