What is the Difference Between Function Literal and Values in Scala

Function Literal vs Function Values

I encountered some bug a couple of weeks ago when trying to play around with partially applied function.

Partial Applied Function is a function that partially created, leaving some of the arguments not applied. While you invoke the function, you can state some of the arguments, and the left argument is supplied when it is required.

Take this for an example:

def add(a: Int, b: Int): Int = a + b 

val addition = add _

addition(1,2) // 3

However, when I try to do it in function literal:

val add = (a:Int,b:Int) => a+b
// add: (Int, Int) => Int = $$Lambda$844/[email protected]

val addition = add _
// addition: () => (Int, Int) => Int = $$Lambda$845/[email protected]

addition(1,2) // this doesn't work

addition()(1,2) // 3

Makes we wonder the difference between function literal and function value.

In the scala book, the definition of function literal and function value is at the compile and run time.

For function literal, (anonymous function or val function), will be compiled into Function2 trait under the hood. Usually, they snap it with an apply method that also is run as a def function (value function).

Therefore, if you assign to a val as an anonymous function, the scala will transform it into a singleton object that has a function apply.

final class anonFun extends scala.runtime.AbstractFunction2 {
    final def apply(a: Int, b:Int) = a + b
}

val add = new anonFun();

When you assign the function literal to another variable as a, the variable will also be created with another object that has another apply method - causing it becoming a higher-order function () => () => something.

However, function values, def function, in scala is served as a regular method in Java. Therefore, when you write def and assigned it to another variable, that variable is getting the method that has access to other members variable in that class. Therefore, the compiler does not create a Function2 trait and an apply method.

It creates an instance method of the object

package <empty> {
  object Main extends Object {
    def add(a: Int, b:Int): Int = a.+(b);
    def <init>(): Main.type = {
      Main.super.<init>();
      ()
    }
  }
}

Main Takeaway:

  • Function literal, val function, is compiled into a class when instantiated at run-time is a function value. It becomes the object itself.
  • If you assign another variable as a partially applied function to a function literal, it created another object literals that have an apply method slap into it. Therefore, creating a higher-order function.
  • If you use function value, a def function compiles into a method in Java. Therefore, it becomes an instance method of an object.

Like this Article?

Sign up for my newsletter to get this content weekly!

Subscribe

* indicates required

Related Posts

3 Useful Things About Either That You Want To Know

Either helps you construct better error handling

Let Me Teach You How To Implement Monad With Cats

Create your own Custom Monad with Cats Library

How to Construct an Immutable Queue

Constructing an Immutable queue with State Monad

How To Randomly Split Up An Elements From A Stream Of Data In Percentage

How to randomly split up element from a stream of data without knowing the total amount of it?

Demystify Builder Pattern in Scala

It is surprisingly simple to create a Builder Pattern in Scala