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:
There code in fact is translated to
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
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:
- The name parameter is not a parameter but a function with 0 arguments
- 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
- 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:
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.