Function Literal referencing by val and def

143 Views Asked by At

I'm trying to understand the crucial difference between these two approaches of referencing / defining Function Literal (reference to anonymous function):

By val

scala> val v2 = new Function[Int, Int] {
     | def apply(a: Int): Int = a + 1
     | }
v2: Int => Int = <function1>

And by def

scala> def f2 = new Function[Int, Int] {
     | def apply(a: Int): Int = a + 1
     | }
f2: Int => Int

It seems that it pretty much the same in terms of use. I either can pass v2 or f2 to the function that accepts (Int) => Int as an argument. Passing arguments to its..

I guess or the case of v2 it creates an Function1 object that refers to the Function1 object.. like a proxy?

Ok.. My question is: what is advantage and disadvantages of 1th and 2nd approach?

And of it is defined by def, is it still Function Literal?

1

There are 1 best solutions below

3
On BEST ANSWER

First of all, neither of your examples are actually function literals—you're creating a Function instance in the plain old sugar-free way, and in fact you could use this approach (new Function { ... }) to create an instance of scala.Function from Java code.

The following are both function literals, and are exactly equivalent to your definitions:

val v2 = (a: Int) => a + 1
def f2 = (a: Int) => a + 1

The only real difference here is that the val will create a single instance once and for all, no matter how many times you use v2 (and even if you never use it), while the def will create a new instance every time (or not at all, if you never use it). So you'll generally want to go with a val.

There are cases, however, where you need to use def. Consider the following:

def myIdentity[A] = (a: A) => a

There's no way we could write this as a val, since Scala doesn't have polymorphic functions in this sense (for any instance of Function[A, B], A and B have to be concrete types). But we can define a polymorphic method that returns a function, and when we write e.g. myIndentity(1), the A will be inferred to be Int, and we'll create (and apply) a Function[Int, Int] exactly as you'd expect.