Incerteza
Incerteza

Reputation: 34934

By-name parameters or functions?

I found out that by-name parameters and functions are very similar. What is the advantage the first ones against the second ones?

object ws1 {
  def myByFunc(f: () => Int) = f()                //> myByFunc: (f: () => Int)Int
  def myByName(f: => Int) = f                     //> myByName: (f: => Int)Int

  def testFunc(a: Int) = a * a                    //> testFunc: (a: Int)Int

  myByFunc(() => testFunc(123))                   //> res0: Int = 15129
  myByName(testFunc(123))                         //> res1: Int = 15129

}

UPDATE: Regarding the question of how many times each of them executes:

object ws1 {
  def myByFunc(f: () => Int) = {
    println("111111111 myByFunc")
    f()
  }                                               //> myByFunc: (f: () => Int)Int

  def myByName(f: => Int) = {
    println("22222222 myByName")
    f
  }                                               //> myByName: (f: => Int)Int

  def testFunc(a: Int) = a * a                    //> testFunc: (a: Int)Int

  myByFunc(() => testFunc(123))                   //> 111111111 myByFunc
                                                  //| res0: Int = 15129
  myByName(testFunc(123))                         //> 22222222 myByName
                                                  //| res1: Int = 15129
}

For some reason they both execute 1 time. Why?

UPDATE2: Neither of them is evaluated:

object ws1 {
  def myByFunc(f: () => Int) = {
    println("111111111 myByFunc")
  }                                               //> myByFunc: (f: () => Int)Unit

  def myByName(f: => Int) = {
    println("22222222 myByName")
  }                                               //> myByName: (f: => Int)Unit

  def testFunc(a: Int) = {
    println("hello from test func")
    123456
  }                                               //> testFunc: (a: Int)Int

  myByFunc(() => testFunc(123))                   //> 111111111 myByFunc
  myByName(testFunc(123))                         //> 22222222 myByName
}

Upvotes: 1

Views: 91

Answers (1)

Yann Moisan
Yann Moisan

Reputation: 8281

It's seems similar but the intent is different :

  • () => Int is a function, more precisely Function0 : it take no parameter and return an Int. The execution of the function is triggred by call of f().

  • => Int is a parameter, passed with a call-by-name technique : The evaluation will be lazy. The code can never be evaluated : def myByName(f: => Int) = 1 or be evaluated multiple times : def myByName(f: => Int) = f * f.

For a more complete explanation, take a look at this question : What's the difference between => , ()=>, and Unit=>

Upvotes: 1

Related Questions