- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
A Taste of 2.8: Named and Default Arguments
Created by rytz on 2009-06-03.
Updated: 2009-06-04, 16:07
Scala 2.8 offers the possibility to call methods using "named arguments", which means specifying the arguments based on the parameter names (instead of the parameter positions). Named arguments help to avoid confusing parameters of the same type and improve code readability.
def resize(width: Int, height: Int) = { ... } resize(width = 120, height = 42)
Furthermore, Scala 2.8 allows providing default arguments on method parameters. In current versions of Scala, default arguments have to be implemented manually using method overloading. This causes some level of code duplication which can be avoided using default arguments.
def f(elems: List[Int], x: Int = 0, cond: Boolean = true) f(List(1)) f(Nil, cond = false)
The example also shows how named arguments allow to selectively use defaults of a method: the second application to f uses the default for x, but not the one for cond.
Compiler-generated copy methods
One very useful application of named and default arguments are the compiler-generated "copy" methods in case classes, which allow to create modified copies of an instance using a lightweight syntax. The copy method takes the same type and value parameters as the primary constructor of the case class, and every parameter defaults to the corresponding constructor parameter:
case class A[T](a: T, b: Int) { // def copy[T'](a: T' = this.a, b: Int = this.b): A[T'] = new A[T'](a, b) } val a1: A[Int] = A(1, 2) val a2: A[String] = a1.copy(a = "someString")
Download a recent nightly build (linux-mac / windows) to try out named and default arguments yourself! To read more about named and default arguments, have a look at the corresponding SID.
- Login or register to post comments
Printer-friendly version
Re: A Taste of 2.8: Named and Default Arguments
It would be nice if there was some mentioning of nested-annotations in 2.8 as a result of this as I understand named argument is a prerequisite for it to work.
Re: A Taste of 2.8: Named and Default Arguments
Right, nested java annotations are supported in Scala 2.8:
Compatibility/recompilations
I wonder how it is implemented behind the scenes.
Let's imagine I got third party library LIB and my application APP (3rd party library in scala! let's suspend disbelief for a moment ;)
1) Assuming I don't have sources for LIB, will I get benefits of default values ? Named parameters ?
2) Let's imagine one of the methods in LIB, compute(param: Something). I compile APP against this version of LIB. Now, new version of LIB appears, when they want to add optional parameter to the compute method, to add progress listener, compute(param:Something, listener:ProgressListener = MockListener) (with MockListener being a no-op singleton default). Obviously, if I recompile APP against new LIB sources, everything will work correctly (I don't want to use ProgressListener in APP). But what will happen if
a) I will just run same APP jar with new LIB jar ? Will default parameter be added automatically ?
b) if a) is not working, is it enough to recompile APP versus binary LIB (probably same answer as point 1 above)
3) If I have method add(x:Int, y:Int = 0) in LIB and compile APP against it, then have new version of LIB which changes definition to add(x:Int, y:Int = x+1), will I get it working by
a) just dropping in new binary version of LIB ?
b) recompiling APP versus binary version of LIB ?
Re: Compatibility/recompilations
Re: Compatibility/recompilations
Point 2 is bit disappointing - for me, one of the possible uses of default parameters was library evolution. It seems that in this case, for method parameter extension, it will be needed to fall back to normal java-like overloading of methods and have two methods implemented, one calling another with 'default' parameter.
Re: A Taste of 2.8: Named and Default Arguments
Do Scala autors consider adding some annotation (i'll name it here @GernerateWithDefaults) that would do following? It can be applied to a class C whose contructor contain N arguments, M of which has default values (M > 0). If applied compiler generates M additional contructors all with different number of arguments (N-M ... N-1). Each of these constructors can have following implementation: def apply(v1: T1, ... vk: Tk) = C(v1, ... vk).
The purpose is to make way to define a classes that would be friendly both to Scala codes and to Java frameworks. Because some frameworks need a class to have no-arguments constructor. This will also make Scala and Java code contructing instance of Scala class with default arguments look pritty the same. Example:
@GenerateWithDefaults
case class NamedObject(@BeanProperty var name: String = null);
generated class file would contain two contructors:
NamedObject(String name);
NamedObject();
Re: A Taste of 2.8: Named and Default Arguments
We don't have any plans to make default arguments interoperable with Java. The transfromation you describe could probably be implemented as a compiler plugin.