-1

Say I write a method that takes in a function, and have another function that returns a function. I can write my method like so:

def logParens(f: () => String) = println(f())

Or like so:

def logNoParens(f: => String) = println(f)

And let's say I have a method that returns a string

def foo = "foo"

How come I can pass foo directly into logNoParens, but not logParens? Seems like Scala coerces foo into => foo before passing it into logNoParens.

logParens(foo) // this gives me a type error
logParens(() => foo) // this compiles
logNoParens(foo) // this compiles just fine

What's the difference between => and () =>?

bioball
  • 1,339
  • 1
  • 12
  • 23

1 Answers1

0

in short: () ⇒ String creates a function of type Unit ⇒ String while ⇒ String means lazy value of type String is passed as an argument, hence it is not re-evaluated later in the function body, if referenced.

So it will be evaluated only once when execution reaches it's reference in the code, and not when passed as an argument.

This form is very common for creation of high-order functions that accept somebody, like:

def func(f: ⇒ String) : Either[Exception, String]{
   if (someCondition) {
     Right(f)
   } else {
     Left(new IllegalArgumentException("F can't be evaluated")
   }
}

And the possible usage is:

def doF() {
  func {
    io.Stream.fromFile("path/to/file")
   }
}

ofcourse you could rewrite this as follows:

def func(f: () ⇒ String) : Either[Exception, String]{
  if (someCondition) {
     Right(f())
  } else {
     Left(new IllegalArgumentException("F can't be evaluated")
  }
}

And the possible usage is:

def doF() {
 func {
   case _ ⇒ io.Stream.fromFile("path/to/file")
  }
}

Depending on the context, you may choose former or latter form, those are completely interchangable in the cases described above. The only difference is that if you pass a lazy value to the function - it will be evaluated only once, but if you pass the function reference to the function - the function will be executed and the result of the evaluation passed to the function as many times as it is used in the function.

Aamir
  • 2,380
  • 3
  • 24
  • 54
jdevelop
  • 12,176
  • 10
  • 56
  • 112
  • Seems like it's evaluated each time it's referenced within the function body. `def log(x: => Int) = 1 to 3 foreach { _ => println(x) }; var z = 0; log { z = z + 1; z }` This example logs 1, 2, 3 – bioball Dec 08 '15 at 22:51