Skip to content

Introduction to Scala: val and def

· 2 min

TL;DR#

val function under the hood#

In Scala, a val function is actually a function wrapped within an object

val replicate: (Int, String) => String = (n: Int, text: String) => text * n

will actually be desugared to:

val replicate = new Function2[Int, String, String] {
def apply(n: Int, s: String): String = s * n
}

The magic behind the scene is that each anonymous function is actually an object that extends the FunctionN trait.

// The actual definition is way more complex,
// but the rough idea is the same
trait Function1[T, R] { def apply(v1: T): R }
trait Function2[T1, T2, R] { def apply(v1: T1, v2: T2): R }
trait Function3[T1, T2, T3, R] { def apply(v1: T1, v2: T2, v3: T3): R }

Then why we can call replicate(3, "hello") like a normal function? Because Scala compiler will automatically call the apply method for you.

replicate(3, "hello")
// is equivalent to
replicate.apply(3, "hello")

which makes the code easier to work with.

When def function#

def functions are the most common way to define a function in Scala. They are more informative because:

It’s especially useful when the function signature is complex:

def createDate(year: Int, month: Int, day: Int): Date = ???
// createDate: createDate[](val year: Int,val month: Int,val day: Int) => Date

then the function can be called using named parameters:

createDate(day = 1, month = 1, year = 2025)

will is much more readable and less ambiguous.

def and val function conversion#

def function can be converted to val function easily by using eta expansion:

def replicate(n: Int, text: String): String = text * n // replicate: replicate[](val n: Int,val s: String) => String
val replicateVal = replicate _ // replicateVal: (Int, String) => String