Tuesday, August 25, 2009

Named and default arguments

NOTE: This topic only works with the up-coming Scala 2.8.0. A beta is expected at the end of September but the nightly builds are quite good.

Named and default arguments are a very nice way to reduce boilerplate code. There are two ideas here.

Default Arguments
This allows one to provide a default value to a method argument so that the caller is not required to provide a value if the default is acceptable. This reduces boilerplate code but also allows the signatures of methods to change and not break existing code (although because of the JVM implementation I think a recompile may be required. I have not verified whether that is the case or not).

This is how it reduces boilerplate code. The java way:
  1. int method( int required, int notRequired) { return required + notRequired; }
  2. int method( int required) { method(required,9); }

2 methods are required and as the number of optional argument increase the number of methods increase exponentially and you will likely need several similarly named methods if the parameters do not have differing type.
  1. def method( required:Int, notRequired:Int=0) = required + notRequired

In Scala 2.8+ you can assign a argument a default value which allows you to optionally provide the value or ignore it.

Named Arguments
The second part of the equation is named arguments. Suppose you have the method and all arguments have different values:
  1. scala>def bigMethod( p1:Int=1, p2:Int=2, p3:Int=3, p4:Int=4, p5:Int=5) = p1 +p2 + p3+ p4 + p5
  2. bigMethod: (p1: Int,p2: Int,p3: Int,p4: Int,p5: Int)Int
  3. scala> bigMethod()  // you have to provide () when default params are used
  4. res10: Int = 15

How can you provide a argument for p3 only? Named arguments to the rescue.
  1. scala> bigMethod( p3 = 10 )
  2. res0: Int = 22

Using named arguments you can declare which arguments you are assigning which value. This works with methods with no default argument as well but is particularly important in conjunction with default arguments.

More examples:
  1. scala>def bigMethod( p1:Int=1, p2:Int=2, p3:Int=3, p4:Int=4, p5:Int=5) = p1 +p2 + p3+ p4 + p5
  2. bigMethod: (p1: Int,p2: Int,p3: Int,p4: Int,p5: Int)Int
  3. scala> bigMethod( p3 = 10 )
  4. res0: Int = 22scala> bigMethod( p3 = 10, p1=11 )
  5. res1: Int = 32
  6. scala> bigMethod( 10,10,10 )
  7. res3: Int = 39
  8. scala> bigMethod( 10,10,10, p5 = -100 )
  9. res5: Int = -66
  10. scala>def anotherMethod( p1:Int, p2:Boolean) = println( p1, p2 )
  11. anotherMethod: (p1: Int,p2: Boolean)Unit
  12. scala> anotherMethod(1,false)
  13. (1,false)
  14. scala> anotherMethod(p2=false, p1=10)
  15. (10,false)
  16. // anotherMethod does not have default args so you must declare all args
  17. scala> anotherMethod(p2=false)
  18. :6: error: not enough arguments for method anotherMethod: (p1: Int,p2: Boolean)Unit.
  19. Unspecified value parameter p1.
  20.        anotherMethod(p2=false)
  21.                     ^

No comments:

Post a Comment