Saturday, March 28, 2009

Nullable AnyVal in Scala

DISCLAIMER: Please don't treat it too seriously. And never ever use the following code for anything serious.

Usually we want to get rid of potential nulls in the code. Here I'll go the opposite way...

All things in Scala are instances of classes. Full OO. The base type for everything is Any. On the other hand there are simple types (still objects!) that inherit from AnyVal and complex types that inherit from AnyRef.

Classes in AnyVal family represent primitive types from underlying (JVM) platform. The compiler makes the decision when to do (un)boxing, so that everything works optimally and (what's even more important) according Scala semantics.

The very important fact is that in Scala null has type Null. That special class is a subclass of every AnyRef derived class. In practice it means that every variable of type Any, AnyRef or AnyRef's subtypes may have a value null. We say that they are nullable.



This is a cause of many bugs... many programming languages aficionados wish that nulls never existed.

Back to the topic. Variables of type AnyVal (or subtypes) normally can not be nulled.


val anyval1: AnyVal = null
/* error: type mismatch;
found : Null(null)
required: AnyVal
*/


But there is a unique Scala functionality (implicit defs aka. views) and a bug in the compiler that allows for that.


implicit def theOtherNull(n: Null): AnyVal = { object o { var nn: AnyVal = _ }; o.nn }


After defining this view the following code will magically work.


val anyval2: AnyVal = null

println(x == null) // "true" !


Uninitialized variable in classes have to have a value. Even if they are AnyVals there needs to be a special default/uninitialized value. Unfortunately as of now that value is a null from underlying JVM platform. Of course it's a bug, becouse it breaks the type system... even worse thing is that this weird null value can be propagated to other vals/vars of type AnyVal.
In case of the view above it's returned, the type checking part of the compiler assumes that the returned value will be a healthy AnyVal, but it's not so anyval2 get's that forbidden/improperly typed value.

Friday, March 20, 2009

Cloning Scala actors

I thought I'd base one of my projects on Scala actors. On the other hand seeing how actors are dynamically typed reminded me of my experiments with dynamic, clone based languages (Io, Ioke, Self, JavaScript).
The preferred way to create an actor in Scala is something like this:


val anActor = actor {
// here goes the body of an actor.: a loop, call to receive/react, message patterns...
}

The problem is I want to have a function cloneActor() that would return a clone of a scala actor:

val anotherActor = cloneActor(anActor)

Note that (for now) I don't want this actor's state to be cloned, just the body.
Just like if you would clone a human being: genetically identical body, but a fresh, clear memory...
At first I thought about using reflection in order to create new instance of the existing actor.



val reflectivelyClonedActor = anActor.getClass.newInstance // this won't work

Even if it didn't throw a run-time exception it wouldn't clone the body of the actor. :-(
The body is a closure passed to the scala.actor.Actor.actor() method.
Second idea was to just create a new actor in a standard way, but reflectively copy the body... Unfortunately the body isn't kept in a explicitly declared field.
Althought there is a implicitly created synthetic field body$1, it's marked private final by the compiler.

scala> a1.getClass.getDeclaredField("body$1").get(a1)
java.lang.IllegalAccessException: Class can not access a member of class scala.actors.Actor$$anon$1 with modifiers "private final"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at .....

Well it was too tricky in the first place... OK. Out of ideas. Let's look at the source of scala.actor.Actor:

def actor(body: => Unit): Actor = {
val actor = new Actor {
def act() = body
}
actor.start()
actor
}

Interesting thing is that act() has type () => Unit while body has type => Unit.
So we can freely use existing actor's act as a body of new actor. Voila!


def cloneActor(a: Actor) = actor(a.act)

Sure it has it's downsides...
What's more interesting if you want to treat actor as wrappers for threads to use all 8 cores of your shiny new machine:

implicit def intmulact(i: Int) = new {
def *(a: scala.actors.Actor) = (1 to i) map { _ => cloneActor(a) } toList
}

val executors = 8 * actor {
// body of the actor
}

Wednesday, March 11, 2009

Dynamic method calls in Scala

This is a trick that I showed to quite experienced Scala coders and some were surprised by it... Let's give it some persistence in the blogosphere.
If you spent some time hacking Scala you probably heard of "asInstanceOf[T]". Which is a Scala's notation for casting. You probably used it in the way similar to this


serviceRegister.get('serviceIdentifier).asInstanceOf[SomeServiceClass].method()

serviceRegister.get() finds a service implementor in the register and returns base, abstract thing... So to use the service you  need to cast it.
Second thing you probably know as a Scala hacker is structural typing - kind of explicit, type safe duck typing. For example method's parameter may have it's type specified as "an object that has a method that is named "add" and it has two Int parameters and results in an Int".


def callsAdd(obj: {def add(a: Int, b: Int): Int}) { 
    /* does something and calls obj.add() */ 
  }

What happens when you mix both asInstanceOf and structural types?


println( anObject.asInstanceOf[{def add(a: Int, b: Int): Int}].add(1, 2) )

Voila! An easiest way to reflectively call a Java/Scala method in a compiled language.
Compare this to Java's way of doing reflective call:


import java.lang.reflect.*;
    
public class method2 {
   public int add(int a, int b)
   {
      return a + b;
   }
    
   public static void main(String args[])
   {
      try {
        Class cls = Class.forName("method2");
        Class partypes[] = new Class[2];
         partypes[0] = Integer.TYPE;
         partypes[1] = Integer.TYPE;
         Method meth = cls.getMethod(
           "add", partypes);
         method2 methobj = new method2();
         Object arglist[] = new Object[2];
         arglist[0] = new Integer(37);
         arglist[1] = new Integer(47);
         Object retobj 
           = meth.invoke(methobj, arglist);
         Integer retval = (Integer)retobj;
         System.out.println(retval.intValue());
      }
      catch (Throwable e) {
         System.err.println(e);
      }
   }
}

About the weird title of this blog

Some of you may wonder why I named my blog in such a hard to remember, user unfriendly way. (Hint: Use RSS or bookmark it. Don't try to remember it...)
 
"Dzhigital" is a neologism I just came up with after reading on wikipedia about "dzhigit" and seeing this picture. (compare to this)
 
This reflects what I like the most in coding and what I'll cover here in this blog... Dangerous, experimental, tricky stuff on powerful horses... err... languages (Scala, Haskell or dynamic ones).

The stuff that usually nobody wants to pay you for... 

If you're a bit like me you won't care. You love coding (programming, developing or playing with abstractions and languages) and you'd keep on doing it even if (especially) it was forbidden. :-)