Scala has both methods and functions in Scala. We refer them interchangeably but there are situations where the difference matters. In the slides, we'll talk about Eta expansion in scala.
2. Agenda
● Method vs Function
● FunctionN Trait
● Partially Applied Functions
● Eta Expansion
3. Method vs Function
Methods == Functions ?
//method
def isEven(x: Int): Boolean = x % 2 == 0
//function
val isEven = (x: Int) => x % 2 == 0
4. Method vs Function
Methods == Functions ?
//method
def isEven(x: Int): Boolean = x % 2 == 0
//function
val isEven = (x: Int) => x % 2 == 0
No, methods and functions are not the same thing in scala. We
do refer both interchangeably but there are many situation
where difference matters a lot.
5. When we create a function using def, then it is a method and
when you create using val, then it is a function in Scala.
A method belongs to an Class whereas function is a complete
object in Scala.
Function can be assigned to a variable but method can’t. In
other words, methods in scala are not values but functions are.
Methods on the other hand are not values; they don’t have a
type and cannot exist on their own (they are an attribute of a
structure in which they are defined, e.g. a class, object or trait)
6. FunctionN Trait
Function is a complete object in Scala.
Every Function you’ll ever define in Scala, will become an
instance of an Implementation which will feature a certain
Function Trait.
There are a series of traits in Scala to represent functions with
various numbers of arguments: Function0, Function1, Function2
, upto Function22
7. Example
val isEven = (x: Int) => x % 2 == 0
val isEven = new Function1[Int, Boolean]{
def apply(x: Int) = x % 2 == 0
}
Here Scala Compiler converts the function into a Function1
trait under the hood.
8. Partially Applied Functions
def product(a: Int, b: Int) = a * b
Suppose you always want to double the values. So instead of
sending 2 everytime, we could create another function having
one parameter 2 set.
val prod = product(2, _ :Int)
Since we have not applied all arguments, prod is the partially
applied function of partially applied application.
A partially applied function is an expression in which you don’t
supply all of the arguments needed by the function. Instead you
supply some or none of the needed arguments.
9. Partially applied functions gives us facility to create specialized
functions on top of particular function.
For example, we can have specialized functions like
doubleValue, tripleValue from product function.
val doubleValue = product(2, _: Int)
val tripleValue = product(3, _:Int)
10. Eta Expansions
val list = List(1 to 10: _*)
list.filter(isEven)
filter takes a function as a parameter and we passed a method
isEven to it and Scala compiler does not throw compilation error.
The reason is Scala compiler does the automatic eta conversion
under the hood.
11. According to Scala Language Specification,
“Eta-expansion converts an expression of method type to an
equivalent expression of function type.”
There are times when compiler is not expecting a function so it
will not automatically convert the method into a function.
So there are two ways to do explicit eta conversion:
1. explicitly declare the type of value to be a function
2. treat the method to be as partially applied function.
12. Example
def isEven(x: Int) = x % 2 == 0
val even: Int = > Boolean = isEven
or
val even = isEven _
val even = new Function1[Int, Boolean]{
def apply(x: Int) = isEven(x)
}
13. When we do explicit eta conversion, What Scala Compiler does
under the hood that it creates anonymous class which
implements the FunctionN trait where, in apply method, it calls
to isEven method.
Eta expansion gives us the power of treating method as function
value and pass it around like another value.
There is need to provide enough type information to
disambiguate in case of method overloading.