adding nodes in ASCII art – part 2

31 01 2008

I wrote a follow up on my article JCR with Scala: adding nodes in ASCII art over at my employers blog.

I discuss the goals I had in mind when designing the ‘ASCII art’ operators. This helps in understanding how these operators actually work and serve as preparation for a later post where I will show how properties fit into the picture.

Advertisements




Adding nodes in ASCII art (update)

23 01 2008

I just fixed the Treebuilder code from my previous article. It seems that this stupid editor keeps eating random lines from <pre> formated sections.





JCR with Scala: adding nodes in ASCII art

23 01 2008

I just wrote another blog on using JCR with Scala over at dev.day.com. This time I show how to define a new operator that lets you define a JCR tree structure in Scala code in such a way that the code will look like ASCII art.





Implicit double dispatch

18 01 2008

While playing around with JCR and Scala I stumbled over JCR’s Value type. I wanted to be able to handle it in a type safe way by using Scala’s generics. This was not a problem until it came to collection of values. Here is a boiled down version of my problem not directly related to JCR. (The entire code is available on my code page under implicit double dispatch.

Scala allows for polymorphic methods by means of overloading:

def foo(s: String) { ... }
def foo(n: int) { ... }

Calling method foo with either a string or a integer argument will automatically result in a call to the method with the corresponding signature. However, this does not carry over to generic types:

def foo(x: List[String]) { ... }
def foo(x: List[int]) { ... }

Here the Scala compiler will complain about both methods having the same erasure. In a nutshell this means Scala (like Java) erases the type information from List and adds casts to the correct target type behind the scenes. However, this leaves us with the two methods having the same signature which is exactly what the compiler complains about.
If we want to handle lists of ints and strings in specific ways we could try the following:

def qoo[T](x: List[T]) {
  for(y <- x) {
    if (y.isInstanceOf&#91;String&#93;)
      println("Got a string: " + y.asInstanceOf&#91;String&#93;)
    else if (y.isInstanceOf&#91;int&#93;)
      println("Got a int: " + y.asInstanceOf&#91;int&#93;)
    else
      error("Type mismatch")
    }
}
&#91;/sourcecode&#93;
But that way we scarify type safety. What we need is a way to restrict the actual types allowed for the type parameter T to int and string. We can not achieve this using <a href="http://www.scala-lang.org/intro/upbounds.html">bounds</a> <a href="http://www.scala-lang.org/intro/lowbounds.html">since</a> int and string belong to disparate branches of the type lattice. However, in Scala generic type parameters can also be restricted by specifying a <a href="http://www.scala-lang.org/intro/views.html">view bound</a>. We can thus define

def foo[T <% Dispatcher&#91;T&#93;&#93;(x: T) { ... }
&#91;/sourcecode&#93;
for some type Dispatcher&#91;T&#93;. Now foo can be called for any type which is convertible to type Dispatcher&#91;T&#93;. That is, the Scala compiler searches for <a href="http://www.scala-lang.org/intro/implicit.html">implicit methods</a> which take an argument of type T and return a Dispatcher[T]. If we supply such implicit conversion methods for lists of ints and lists of strings we will be able to call foo passing arguments of such types only.

abstract class Dispatcher[T](value: T) {
  def select(switch: Switch)
  def dispatch(switch: Switch)
}

A Dispatcher[T] is involved in a double dispatch. First List[T] is (implicitly) converted to a Dispatcher[List[T]]. The select method of the latter converts each element of List[T] to a Dispatcher[T] instance an calls its dispatch method passing along a Switch instance.

trait Switch {
  def case_(s: String)
  def case_(n: int)
}

In the second step the dispatch method calls the case_ method on the Switch instance passing along the wrapped value. Finally we need the conversion methods for the implicit conversions:

implicit def string2Disp(value: String) = new Dispatcher(value){
def select(switch: Switch) {}
def dispatch(switch: Switch) {
switch.case_(value)
}
}
implicit def int2Disp(value: int) = new Dispatcher(value){
def select(switch: Switch) {}
def dispatch(switch: Switch) {
switch.case_(value)
}
}
implicit def list2Disp[T](value: List[T])(implicit x2Disp: T => Dispatcher[T]) =
new Dispatcher(value) {
def select(switch: Switch) {
for(x <- value) { x2Disp(x).dispatch(switch) } } def dispatch(switch: Switch) {} } [/sourcecode] Now we can use these conversions in the implementation of foo like this: [sourcecode language='java'] def foo[T <% Dispatcher[T]](x: T) { x.select(new Switch { def case_(x: String) { println("Got a string " + x) } def case_(x: int) { println("Got a int " + x) } }) } [/sourcecode] Calling foo will now succeed only on lists of ints and lists of strings: [sourcecode language='java'] foo("11"::"12"::Nil) foo(12::5::Nil) foo(12.12::3.15::Nil) [/sourcecode] The first two lines will compile fine while on the third line the Scala compiler reports an error since it cannot find a matching implicit conversion from List[double]) to Dispatcher[List[double]]. If strings and ints provided for a dispatch mechanism by themselves, I could have saved me the trouble by just using these. Instead I had to mimic extension methods for the former using Scala’s Pimp my library pattern.





JCR with Scala

16 01 2008

I recently got interested in Scala. Since my current work is related to JCR I decided to give it a try with Scala. See my post on my employers blog for a first impression.

I will blog here once in a while about my work with JCR and Scala.