0

The Scala compiler will not evaluate a method, it just determines its argument and return types. The Scala compiler evaluates assignments.

I'm basing these statements on the evaluation of below statements :

    //create a function which accepts two int parameters and returns their sum
  def f(a: Int, b: Int) = a + b                   //> f: (a: Int, b: Int)Int

  //create a function which returns the sum of 1+2
  def fh = f(1, 2)                                //> fh: => Int

  //The use of val forces the function 'f' to be evaluated :
  val vh = f(1, 2)                                //> vh  : Int = 3
blue-sky
  • 51,962
  • 152
  • 427
  • 752
  • 1
    Your definition looks a bit complicated for me. I'd say: `val` stores result of evaluation while `def` re-evaluates each time. – ie. Mar 12 '15 at 10:08
  • 2
    Well... the value of a `function` is an `expression` and whenever this `function` is called the `expression` is evaluated whereas the value of a val is the evaluated value itself. Basically when you do `def a = 5 + 2`, `a` is a function of type `() => Int` whose value is `expression` - `5 + 2` ( note that `5 + 2` is treated as an `expression` and not as the `value` `7` ) which will evaluate to value `7` each time you will call `a`. But if you did `val a = 5 + 2`, the value of `a` will be the evaluated value of expression `5 + 2` which is `7`. – sarveshseri Mar 12 '15 at 10:14
  • 2
    It all boils down to understanding the fact that function languages like to deal with `expressions` and in purely functional languages every statement is an `expression`. So... `5` is actually an `expression` of type `() => Int` and `println( 5 )` is an expression of type `() => Unit`. – sarveshseri Mar 12 '15 at 10:24
  • 1
    In addition to @SarveshKumarSingh You can consider `def f(a: Int, b: Int) = a+b` as syntactic sugar for `val f = (a: Int, b: Int) => a+b`. And given that Scala is not only functional but also object-oriented, this is the same as `val f = new Function2[Int,Int,Int] { def apply(a: Int, b: Int) : Int = a+b }`. – godfatherofpolka Mar 12 '15 at 11:53
  • See also http://stackoverflow.com/questions/9449474/def-vs-val-vs-lazy-val-evaluation-in-scala for more information directly applying to your question. – godfatherofpolka Mar 12 '15 at 12:00

2 Answers2

2

Let's look at the following console output:

scala> def f(a:Int, b:Int) = {
     | println("f called...")
     | a+b
     | }
f: (a: Int, b: Int)Int

scala> f(1,2)
f called...
res4: Int = 3

I slightly modified function definition. Now when we invoke f, it will print out f called...

scala> def fh = f(1,2)
fh: Int

scala> fh
f called...
res5: Int = 3

When you type fh and hit Enter key, fh, which is f(1,2) is executed. You can see that f called... is printed on the console. Whenever fh is evaluated, f called... will appear on the screen.

scala> val vh = f(1,2)
f called...
vh: Int = 3

scala> vh
res6: Int = 3

When you type vh, it will not print out a message. What's difference? fh is just an alias of f(1,2) and it will call f when fh is evaluated. On the other hand, vh is just a value initialized with the result of f(1,2).

ntalbs
  • 28,700
  • 8
  • 66
  • 83
0

In short:

  • def is evaluated every time it is accessed
  • val is evaluated only the first time it is encountered
  • there's a third type of declaration, lazy val, that is evaluated only the first time it is used--if it does not throw an exception, otherwise it's re-evaluated

This last point is not widely known since most people think lazy val is evaluated only the first time is used regardeless of exceptions. The following example demonstrates it:

scala> var n = 1  
n: Int = 1

scala> lazy val x = if (n == 1) sys.error("Not Ready") else 42  
x: Int = <lazy>

scala> x  
java.lang.RuntimeException: Not Ready  
...

scala> n = 0  
n: Int = 0

scala> x  
res1: Int = 42

scala> n = 1
n: Int = 1

scala> x  
res2: Int = 42
lambdista
  • 1,850
  • 9
  • 16