Functions vs methods in Scala
Solution 1:
Under the hood, there are other differences between functions and methods. Generally, a plain method generated less overhead than a function (which technically is an object with an apply
method).
However, if you try not to care about those differences and think of def
, val
and var
as fields with different semantics, then it’s simply that def
evaluates every time it gets called while val
evaluates only once.
So, a val isEven = isDivisibleBy(2)
should call isDivisibleBy(2)
during its definition and assign the result of isDivisibleBy(2)
. E.g. it replaces the k
in
def isDivisibleBy(k: Int): Int => Boolean = i => i % k == 0
with 2
and assigns the result of the final expression (in this case there is only one expression):
val isEven: Int => Boolean = i => i % 2 == 0
def isEven
on the other hand does no such evaluation and results in a call to isDivisibleBy(2) every time.
That means, later, when you execute the code, isEven(11)
generates in case of a val
11 % 2 == 0
and in case of a def
, you’ll have
isDivisibleBy(2)(11)
and only after evaluating isDivisibleBy
you’ll get the result.
You can add some debug code to isDivisibleBy
to see the difference:
def isDivisibleBy(k: Int): Int => Boolean = {
println("evaluating isDivisibleBy")
i => i % k == 0
}
Solution 2:
I'd like to address another point here. This defines isEven
as a method:
def isEven = isDivisibleBy(2)
And this defines isEven
as a method as well:
val isEven = isDivisibleBy(2)
In both cases, isEven
is a method which, when called, return a function.
In the first case, isDivisible(2)
is called every time isEven
is called. For example, this calls isDivisible(2)
three times:
def isEven = isDivisibleBy(2)
List(1,2,3).filter(isEven)
In the second case, isDivisible(2)
is called once (at construction time, or when that line in a definition is executed), and that value is retrieved every time isEven
is called. The following example calls isDivisible(2)
one time only:
val isEven = isDivisibleBy(2)
List(1,2,3).filter(isEven)
Solution 3:
I think that the main pro of defining the function isEven
as val
is to show to audience that the function can be defined this way. Then it's clear, that a function is just an object like everything else in scala. But in the world of non-demonstrating programming, there's no need to write functions as val
s.