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.

No comments:

Post a Comment