Sunday, October 7, 2012

Scala: Named parameters behind the scenes

One interesting technique scala introduces is Named parameters. The named parameters can be defined by the following construct paramName: => Type

There is an essential difference between parameters passed by value and passed by name: "The parameter passed by name is calculated only if it's needed"

Consider the following example:

  def and(a: Boolean, b: => Boolean) = if (a) b else false
  def or(a: Boolean, b: => Boolean) = if (a) true else b
  def sqr(x: => Int) = x * x 
There code in fact is translated to
    public boolean and(boolean a, Function0 b)  {
        return a ? b.apply() : false;
    }

    public boolean or(boolean a, Function0 b) {
        return a ? true : b.apply();
    }

    public int sqr(Function0 x) {
        return x.apply() * x.apply();
    }
by Scala compiler. Let's examine it:
  1. The name parameter is not a parameter but a function with 0 arguments
  2. The function is calculated on demand
      and(true, scala.util.Random.nextInt() > 1000) ////random is executed
      and(false, scala.util.Random.nextInt() > 1000) //random isn't executed
      or(true, scala.util.Random.nextInt() > 1000) //random is executed
      or(false, scala.util.Random.nextInt() > 1000) //random isn't executed
    
  3. The function executes  every time the param is accessed, there is no caching of calculated values. It's important thing to be aware of. For example:
  4.  
      sqr(scala.util.Random.nextInt()) 
      //it returns scala.util.Random.nextInt() * scala.util.Random.nextInt()
    
    the call most likely doesn't return a square of a random int.

The named parameters are very useful when you understand the idea behind them. Hope this post helps people to avoid common problems with named parameters.

Thursday, October 4, 2012

Sorting Mongo collection with Spring Data

One of my friend (a smart guy and a good developer) came up to me with a question "I'm trying to sort the results and I follow the documentation but still no luck" then he provded the code to find a problem:
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Sort;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;

public interface EventRepository extends PagingAndSortingRepository<ApplicationEvent, ObjectId>{
    @Query("{'created' : {$lt: ?0}, 'status': ?1, 'active':true}")
    List<ApplicationEvent> findAllByStatus(long date, String status, Sort sort);
}
At first look everything is ok, the class is designed in according to docs and tutorials. It just didn't work. What's wrong with this code? After awhile we'd figured it out. The answer is when you try to sort results with Spring Data and Repositories and the underlying database is Mongo, please check twice if you aren't using
import org.springframework.data.mongodb.core.query.Sort;
insted of
import org.springframework.data.domain.Sort;
It's so embarrassing, but after replacing with to the right one everythig just started working..

Tuesday, October 2, 2012

Scala: Lazy values behind the scenes

Scala introduces some syntactic sugar to shorten the code we produce. One of them is lazy values. It's wonderful how fast a lazy initialization can be defined and used just by adding a single word 'lazy' for any value almost anywhere...

class LazyValue {
  lazy val x = 10
  lazy val y = "20"
}

Easy, isn't it? The values 'x' and 'y' are initialized with a first time access and a syntax to define this is so compact. But behind the scenes the lazy values are a bit more complicated. This is how scala compiler unwrap lazy values:

import scala.ScalaObject;

public class LazyValue implements ScalaObject {
    private int x;
    private String y;
    public volatile int bitmap$0;

    public int x() {
        if ((this.bitmap$0 & 0x1) == 0)
            synchronized (this) {
                if ((this.bitmap$0 & 0x1) == 0) {
                    this.x = 10;
                    this.bitmap$0 |= 1;
                }
            }
        return this.x;
    }

    public String y() {
        if ((this.bitmap$0 & 0x2) == 0)
            synchronized (this) {
                if ((this.bitmap$0 & 0x2) == 0) {
                    this.y = "20";
                    this.bitmap$0 |= 2;
                }

            }
        return this.y;
    }
}

Notice that instead of checking x==null and y==null scala uses bitwise operations on the volatile bitmap$0, a good practice by the way.  If we have more than 32 lazy fields then the bitmap$1 is introduced

The code has an issue we have to be aware of: the initialization is synchronizing on this. So when we'r working with lazy values we have to keep in mind the following:

  1. Accessing to a lazy val might lock our object (all it's synchronized methods and lazy vals) and vise-versa. 
  2. When we use lazy vals on objects we have to be super-careful cause deadlock is the thing we can face when using the cross-object initialization of lazy vals
The example bellow demonstrates how to get a deadlock with a minimal effort :)

object Deadlock {
  object A {
    lazy val x: Int = {
      val cdl: CountDownLatch = new CountDownLatch(1)
      new Thread(){
        override def run() {
          print(B.x)
          cdl.countDown()
        }
      }.start()
      cdl.await()
      10
    }
  }

  object B {

    lazy val x = A.x
  }

  def main(args: Array[String]) {
    print(B.x)
  }
}

Of course it's a synthetic example but it gives us an understanding that the parallel initialization of lazy values might be dangerous.

Summary: Use of lazy vals shorten our code by removing some boilerplates (in comparison to Java) but they should be used with an idea in mind that the initialization of lazy values is not an atomic operation and can lead to deadlock.