Sunday, May 29, 2011

A touch of Scala

Since a few month now the shadow of functional programming has started haunting me. A few months ago I started again gazing at Scala, Ruby and would really like to go into Clojure. As all these languages can be run onto a JVM, practicing them brings an interesting merge between Object Oriented paradigm and functional programming paradigm (OMG I'd like to try LISP and Erlang some day). As it is difficult to find masters of these crafts in France (hum... some may know what I mean...), I started contacting foreign companies in border countries, but these things take time. So in order to improve the knowledge, I bought the Martin Odersky's Scala reference (Programming in Scala) , the pragmatic book approach of Venkat Subramaniam, and a recent book from Artima about Actors in Scala from Philipp Haller and Frank Sommers (because I'd like so much to code some Erlang !!!).

I have adopted the approach suggested by Jonas Boner in an infoQ presentation, starting from a bird eyes view and then going deeper in to the code. This learning involved starting with Venkat book and then going to the actors book, using the big programming book as an incredible powerful reference (reading it teaches you a lot about Scala, Java... and yourself).

Humility implies going back and going back again to basics and one pleasant way to do it, is trying to grab presentations on channels. As I was recently looking at some Martin's Odersky's presentation, he provided quite an interesting short topic about how to implement a try-with-resource jdk7 (TWR) stuff but as a Scala implementation. This is a small interesting part for a newbie like me because this small example gathers some typical features of Scala.
The presentation was made in 2009, when the jdk7 was not even a beta version.

We talked about the TWR feature in jdk earlier. Basically, this feature reproduces the C#.NET language enhancement allowing to declare a closeable resource in a try expression that would ensure on your behalf that the resource is closed (works for I/O streams, bundles, JDBC connections etc...):

try (final AsynchronousFileChannel sourceChannel =...
     final AsynchronousFileChannel targetChannel =...
     ) {
         final ByteBuffer buffer = allocateDirect(65536);
         final CountDownLatch countDownLatch = new CountDownLatch(1);
         final SourceCompletionHandler handler =
                 new SourceCompletionHandler(
                         sourceChannel, targetChannel, buffer, countDownLatch
                 );
         sourceChannel.read(buffer, 0, null, handler);
         countDownLatch.await();
     }

and channels are closed by the underlying JVM plumbing.

How would I want to implement it in Scala ?
Naturally I started with some testing code in order to foresee how I would like to write this invocation.
Basically I would like to create a closeable resource, invoke what I have to invoke and bang, done!
It is a start, so I wrote

import org.junit.Test
import org.junit.Assert._
import  com.promindis.tools.CloseableUtils._


final class TestCloseUtils {

  @Test
  def  using_StubCloseable_ShouldFireCloseAction()  {
    val closeable = SpyingCloseable()
    
    using(closeable) {
      closeable => closeable.invoke();
    }

    assertTrue(closeable wasInvoked)
    assertTrue(closeable wasClosed)

  }
}

In order to trace trace that, both the closeable would be invoked and, that the method close would be applied I wrote a small Spying class:

class SpyingCloseable {
  var closed = false
  var invoked = false

  def close() { closed = true}
  def invoke() {invoked = true}

  def wasClosed() = closed
  def wasInvoked() = closed

}

object SpyingCloseable {
  def apply() = {
    new SpyingCloseable
  }
}

Indeed I wrote a class definition and the implementation of the "companion" object. As there are no statics methods nor field objects  in Scala, you can create an object instance very close to Martin Fowler's knowledge level implementation of your class. This object provides you with class level utilities and particularly you have the opportunity to define a default behavior implementing an apply() method. Creating an apply method allows you to create instance without the new keyword.

Basically the spy caches whether you've called the expected methods.

The natural elegance of the Scala syntax makes the class content easily readable even for a novice. The purist will not be very happy with the variable instance which by definition are mutable and in functional programming, mutability should have not place to live in. But it is a test so I beg your pardon.

So how does look like the implementing class ? Very close to Martin Odersky's demo:

object CloseableUtils {

  def using[T <: {def close()}]
                    (resource: T)
                       (block: T => Unit){

    try {
      block(resource)
    } finally {
      if (resource != null) resource.close()
    }
  }

}

Firts of all I wanted my class to accept all possible closeable resources. So my method - as in Java Generics - must accept all kinds of derived definitions of closeable. In one word I must apply type inference rules on my method, using a generic typing parameter: T. As all the handled resources derived from some closeable resource definition, my type is limited by an upper bound type definition. The upper bound definition is provided by the following notation: <: .

What is a closeable ? Indeed everything that exposes a close() method. This is where we can use duck type. Remember :
"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck."

Indulge me and think about this version:

"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I assume that this bird behaves like duck."

Thinking like that opens the path to role driven design. But this is another discussion...

The duck typing implementation of my type is quite simple:

{def close()}

One of my purpose designing this class was providing this feature with a more "native" like look. You know with the open/closed braces that gives this impression of fluency and that you extended the language definition.
Scala allows the developer to apply braces instead of parenthesis on single parameter methods. That would provide this look alike the while control for example. But my utility class has two parameters.
That's where currying and partial functions come into the party. Function (specially idempotent ones) taking multiple input parameters can be seen as a composition of multiple functions. You can than create a partial function instance setting one of the parameters.
For example

def sum(x: Int, y: Int) = x + y

could also be written

def composedSum(x: Int)(y: Int) = x + y

You can then set

val fivePlus = composedSum(5)_

that will create fivePlus as a partial function instance, ready to be invoked with the lasting parameter:

fivePlus(6)

I can do exactly the same with my utility function, splitting the parameters declarations.
So I will be able to invoke

using(closeable) {
      closeable => closeable.invoke();
    }

creating my partial curried function invoking using(closeable). This partial function only accepts one parameter that I can invoke using braces:

def using[...](resource: T)(block: T => Unit)

Tests are green. So now as a little example I can open my pom.xml project file and list its content, sure that my source file abstraction has been closed:

using(fromFile("pom.xml")) { data =>
  println(data.mkString)
}

Thanks to the ones who did not fall asleep =D
Be seeing you !

0 comments:

Post a Comment