How to use parameter names when calling a Scala method

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 5.4, “How to use parameter names when calling a Scala method.”

Problem

You prefer a Scala coding style where you specify the method parameter names when calling a method.

Solution

The general syntax for calling a Scala method with named parameters is this:

methodName(param1=value1, param2=value2, ...)

This is demonstrated in the following example. Given this definition of a Pizza class:

class Pizza {
    var crustSize = 12
    var crustType = "Thin"
    def update(crustSize: Int, crustType: String) {
        this.crustSize = crustSize
        this.crustType = crustType
    }
    override def toString = {
        "A %d inch %s crust pizza.".format(crustSize, crustType)
    }
}

you can create a Pizza:

val p = new Pizza

You can then update the Pizza, specifying the field names and corresponding values when you call the update method:

p.update(crustSize = 16, crustType = "Thick")

This approach has the added benefit that you can place the fields in any order:

p.update(crustType = "Pan", crustSize = 14)

Discussion

You can confirm that this example works by running it in the Scala REPL:

scala> val p = new Pizza
p: Pizza = A 12 inch Thin crust pizza.

scala> p.updatePizza(crustSize = 16, crustType = "Thick")

scala> println(p)
A 16 inch Thick crust pizza.

scala> p.updatePizza(crustType = "Pan", crustSize = 14)

scala> println(p)
A 14 inch Pan crust pizza.

The ability to use named parameters when calling a method is available in other languages, including Objective-C. Although this approach is more verbose, it can also be more readable.

This technique is especially useful when several parameters have the same type, such as having several Boolean or String parameters in a method. For instance, compare this method call:

engage(true, true, true, false)

to this one:

engage(speedIsSet = true,
       directionIsSet = true,
       picardSaidMakeItSo = true,
       turnedOffParkingBrake = false)

When a method specifies default values for its parameters, as demonstrated in Recipe 5.3 (How to set default values for Scala method parameters), you can use this approach to specify only the parameters you want to override.

For instance, the scala.xml.Utility object has a method named serialize that takes seven parameters. However, default values are defined for each parameter in the method declaration, so if you need to change only one parameter, such as whether you want comments stripped from the output, you need to specify only that one parameter, in addition to your XML node:

Utility.serialize(myNode, stripComments = true)

The combination of these two recipes makes for a powerful approach.