3

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?

ses
  • 12,339
  • 25
  • 106
  • 203
  • 1
    Possible duplicate of http://stackoverflow.com/a/18887341/985949 – Mik378 Mar 03 '14 at 02:17
  • See the accepted answer here: http://stackoverflow.com/questions/19607485/def-or-val-for-defining-function-in-scala?rq=1. Basically it's a method (def) vs function object (val), but both are almost the same. – yǝsʞǝla Mar 03 '14 at 02:18

1 Answers1

3

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.

Travis Brown
  • 135,682
  • 12
  • 352
  • 654
  • if they are are exactly equivalent to my definitions and since it is syntax sugar they are supposed to be function literals (?). First I came up with your simple examples - results/outputs seems the same. – ses Mar 03 '14 at 02:56
  • 2
    The term _literal_ in this context refers specifically to the syntax, so you'd call the sugared version a function literal, but not the plain old instantiation via `new`. – Travis Brown Mar 03 '14 at 03:13
  • 1
    @ses `4` and `(2+2)` are exactly equivalent, but the first is an integer literal and the second is not. Same here. – Alexey Romanov Mar 03 '14 at 06:29