0

I'm confused about anonymous function definitions as following:

var plusOne = (x:Int)=>x+1
// or val plusOne=(x:Int)=>x+1
println(plusOne(2))

Or

def plusOne = (x:Int)=>x+1
println(plusOne(2))

What's the difference please in var/val and def for a function name.

elm
  • 20,117
  • 14
  • 67
  • 113
Jack
  • 5,540
  • 13
  • 65
  • 113
  • 1
    Possible duplicate of [Practical difference between def f(x: Int) = x+1 and val f = (x: Int) => x+1 in Scala](http://stackoverflow.com/questions/22354396/practical-difference-between-def-fx-int-x1-and-val-f-x-int-x1-in) – The Archetypal Paul Mar 23 '16 at 06:55
  • This has nothing to with functions. The difference between `var`, `val`, and `def` has nothing to do with their type. `var` and `val` are fields ("variables", if you will), `def` is a method. It doesn't matter what they return. – Jörg W Mittag Mar 23 '16 at 09:13

4 Answers4

8
  • val declares an "immutable variable or rather symbol" that doesn't allow reassignment, right hand side of the assignment is evaluated immediately
  • var declares a "mutable variable" that allows reassignments later to the symbol, right hand side of the assignment is evaluated immediately just like val
  • def declares an "immutable symbol" that doesn't allow reassignment, right hand side is evaluated lazily, i.e. whenever that symbol is referenced later in the code

Example -

var plusOneVar = (x:Int)=>x+1
val plusOneVal = (x:Int)=>x+1
def plusOneDef = (x:Int)=>x+1

plusOneVar = (x:Int)=>x+2 // Reassignment to var is valid
plusOneVal = (x:Int)=>x+2 // Compile time error, reassignment to val
plusOneDef = (x:Int)=>x+2 // Compile time error, reassignment to val

Because you are looking at an example with functions, it is hard to understand. Let's try to understand it with simple variables.

var symbolVar = 100        // line 1
val symbolVal = symbolVar  // line 2
def symbolDef = symbolVar  // line 3

println(symbolVar)  // prints 100
println(symbolVal)  // prints 100
println(symbolDef)  // prints 100 - no surprise yet

symbolVar = symbolVar + 1

println(symbolVal)  // still prints 100 which was evaluated and assigned on line 2
println(symbolDef)  // prints 101 as symbolDef is a def and it depends on symbolVar, line 3 is evaluated again
Pranav Shukla
  • 2,206
  • 2
  • 17
  • 20
2

var plusOne can be reassigned. val plusOne cannot be reassigned. Both are evaluated once. def plusOne is evaluated each time it is called

j will
  • 3,747
  • 11
  • 41
  • 64
1

Note also with val (or var) one instance of the function is created and is used for any number of invocations to that function, whereas with def a new instance of the function is created for each invocation. Yet, for

def f (i:Int) = i+1
f: (i: Int)Int

note

val g = f _
g: Int => Int = <function1>
elm
  • 20,117
  • 14
  • 67
  • 113
0

It might be clear from the Class File Disassembler results using javap. Save the following code as Test.scala

class Test {
  val fVal: Int => Int = x => x + 1
  var fVar: Int => Int = x => x + 1
  def fDef(x: Int): Int = { x + 1 }
}

and do scalac Test.scala; javap Test will show

Compiled from "Test.scala"
public class Test {
  public scala.Function1<java.lang.Object, java.lang.Object> fVal();
  public scala.Function1<java.lang.Object, java.lang.Object> fVar();
  public void fVar_$eq(scala.Function1<java.lang.Object, java.lang.Object>);
  public int fDef(int);
  public Test();
}

As is shown in the results above, val and fVar are represented as methods that return a Function1 object. The difference is fVar has an additional "setter". While fDef is like normal Java method.

sxiang3
  • 1
  • 1