Wednesday, September 19, 2012

Scala Functions Apply

This is a short post about sweet spots of scala functions such as apply, update and case classes using these constructs.

Coming from a Ruby world, developers usually snub at Java claiming Javascript and Java, substring of JS are a mere naming coincidence, without any functional relations. Hmm, perhaps recent hot cake Functional programming which has been tombed in Egypt several thousand years back is a mirage in Java community, where java is targeted for non functional, non mathematical people, who well mutate everything in their life apart from Java. Apparently some serious thought breakers ice sandwiched Java and started exploding JVM that catered to beautiful languages like Scala and Clojure.

Scala bieng a functional language believes in functions being first class citizens with a slight mix of object oriented programming orthogonal to it. This helps in writing clean, concise, expressive code.

Here are some experiments by firing scala REPL,

To define an anonymous function,
val cube = (x:Int) => x * x * x
#cube: (Int) => Int = <function1>
cube(5)
#125
Its clear that it takes an argument Int and returns an Int. Further we can explicitly specify return type say Double,
val cube: (Int) => Double = (x) => x * x * x
#cube: (Int) => Double = <function1>
When I started exploring function1, I landed on to interesting landscape, behind the scenes scala does million number of things by providing this sugar coated pill.

function1 is actually an interface with apply method and anonymous class out of it is created copying the method definition inside apply method. In fact the above cube function could be written in this way too,
val cube: Function1[Int, Double] = (x) => x * x * x
#cube: (Int) => Double = <function1>

cube.apply(5)
#res2: Double = 125.0

cube(5)
#res3: Double = 125.0
look how scala beautifully desugars cube(5) to cube.apply(5).

The Function1 would probably be a interface like this
public interface Function1<A, B> {
    B apply(A a)
}
and creating anonymous class at runtime, copying method definition inside apply method like below(note - below I refer Scala types and not Java)
cube = new Function1<Int, Double>() { Double apply(Int a) { a * a * a }}
cube.apply(5) #actual way
cube(5) #sugar coated pill in Scala
now if I have a polynomial equation, say x^2 + y^2 the thing would be even more beautiful,
val square: Function2[Int, Int, Double] = (x, y) => x * x + y * y
#square: (Int, Int) => Double = <function2>

square(4,5) #square.apply(4,5)
#res0: Double = 41.0
The deduction here is, if n is the size of arguments with last being return type, then the interface name would be function{n-1}.

In the last example we had two unknown variables x, y and return type - hence Function2.

In fact any class with apply method works same way,
class ApplyTest {
    def apply(in: Int) = in + in.toString
}

val applyTest = new ApplyTest()
#applyTest: ApplyTest = ApplyTest@5292e6

applyTest(5) #applyTest.apply(5)
#res0: String = 55

Usage of apply method in real time applications

apply function syntactic sugar could be used to fetch domain object  or model object from a singleton, example
object Employee {
    def apply(id: Int) = "retrieving from database employee object id " + id
}

Employee(5) #res1: java.lang.String = retrieving from database employee object id  5

There is another sugar coated pill in scala - update function which I will cover it in next post.

No comments: