Saturday 6 October 2012

Scala : How functions are treated as objects

Hi friends,
        happy to share some interesting things studied from the on-line course Functional Programming Principles in Scala taken by the creator of Scala himself. Here I am trying to explain how functions are treated as primitive objects in Scala.

Consider Assignment of function
scala> def f(x:Int)=x*x  
f: (Int)Int

scala> var t:(Int)=>Int=f
t: (Int) => Int = <function>
We can also perform such an assignment as follows
scala> var t:Function[Int, Int]=f
t: (Int) => Int = <function>

similerly,
val y:Function2[Int,Int,Int]=(i:Int,j:Int)=>i+j
y: (Int, Int) => Int = <function> 

This gives insight to how functions are actually treated like objects in Scala.

In Scala, Traits Function1, Function2, ...Function22 are defined like follows
package scala
Trait Function1[T,F]
{
    def apply(x:T):F
} 
A function object of type (T) => F is an instance of subclass of Function1[T,F]
We can now define a function of type (Int)=>Int in this very basic way as follows.
class FunClass extends Function[Int,Int] {            
     def apply(x:Int):Int=x*x
}
defined class f
scala> val newFun=new FunClass()
newFun: FunClass = <function>

scala> newFun.apply(9)
res1: Int = 81
This is same as
scala> newFun(9)      
res2: Int = 81 
Now let us create an anonymous function
scala> val f= new Function[Int,Int] {
     | def apply(x:Int)=x*x
     | }

scala> f(9)
res2: Int = 81 

Now look at the apply() function.What happens if The apply itself a function object which with an apply() function as its member? It will lead to an infinite expansion when we create any function objects.

scala> def f(x:Int)=x*x                  
f: (Int)Int

scala> f.apply(9)
<console>:6: error: missing arguments for method f in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
       f.apply(9)
       ^
Why we could not call apply() of object f? No its not. f is not a function object here. Now look back to our first try
scala> var t:Function[Int, Int]=f
t: (Int) => Int = <function>
Here a function object corresponds to f is generated which is an "anonymous function object" and is assigned to variable t while executing these kind of assignment statements. Here it is a simple definition for "eta expansion".

No comments:

Post a Comment