Thursday, August 24, 2017

Functions in Scala

In addition to being functional, Scala is also object-oriented. Hence a function is also an object and can be used wherever a value can be used.

scala> val isEven = (n: Int) => n % 2 == 0
isEven: Int => Boolean = $$Lambda$1002/925024581@4cbc2e3b

scala> isEven(1)
res0: Boolean = false

scala> isEven(2)
res1: Boolean = true

Behind the scenes, each call to isEven(<n>) is being converted to isEven.apply(<n>)

Actually, the isEven function is of type trait Function1[-T, +R] where T = Int and R = Boolean.

Every function in Scala maps to one of the FunctionN traits where N = 0 to 22. Yes, there are only 23 of them which implies that the number of function arguments cannot exceed 22.

Now, why do we need these FunctionN trait definitions in first place?

As Scala allows functions to be defined outside of classes/objects and as Scala is statically typed and is OO implying that functions are objects as well, it becomes essential that functions have to a type. Hence the need for these FunctionN traits.

Also note that the FunctionN types are contravariant w.r.t arguments (T1, T2 etc.) and covariant w.r.t return types (R). This is ensure flexibility so as to conform to the subtyping rule that subtypes should be permissive in what they accept and restrictive in what they produce. For more about this, refer to this nice reddit post by balefrost.







No comments: