Skip to content

Reworked default parameter tour #730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 12, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 21 additions & 47 deletions tutorials/tour/_posts/2017-02-13-default-parameter-values.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,65 +9,39 @@ categories: tour
num: 33
next-page: named-parameters
previous-page: annotations
prerequisite-knowledge: named-arguments, function syntax
---

Scala provides the ability to give parameters default values that can be used to allow a caller to omit those parameters.

In Java, one tends to see a lot of overloaded methods that only serve to provide default values for certain parameters of a large method. This is especially true with constructors:
```tut
def log(message: String, level: String = "INFO") = println(s"$level: $message")

```java
public class HashMap<K,V> {
public HashMap(Map<? extends K,? extends V> m);
/** Create a new HashMap with default capacity (16)
* and loadFactor (0.75)
*/
public HashMap();
/** Create a new HashMap with default loadFactor (0.75) */
public HashMap(int initialCapacity);
public HashMap(int initialCapacity, float loadFactor);
}
log("System starting") // prints INFO: System starting
log("User not found", "WARNING") // prints WARNING: User not found
```

There's really only two constructors here; one that takes another map, and one that takes a capacity and load factor. The third and fourth constructors are there to allow users of <code>HashMap</code> to create instances with the probably-good-for-most-cases defaults of both load factor and capacity.

More problematic is that the values used for defaults are in both the Javadoc *and* the code. Keeping this up to date is easily forgotten. A typical pattern around this would be to add public constants whose values will show up in the Javadoc:
The parameter `level` has a default value so it is optional. On the last line, the argument `"WARNING"` overrides the default argument `"INFO"`. Where you might do overloaded methods in Java, you can use methods with optional parameters to achieve the same effect. However, if the caller omits an argument, any following arguments must be named.

```java
public class HashMap<K,V> {
public static final int DEFAULT_CAPACITY = 16;
public static final float DEFAULT_LOAD_FACTOR = 0.75;
```tut
class Point(val x: Double = 0, val y: Double = 0)

public HashMap(Map<? extends K,? extends V> m);
/** Create a new HashMap with default capacity (16)
* and loadFactor (0.75)
*/
public HashMap();
/** Create a new HashMap with default loadFactor (0.75) */
public HashMap(int initialCapacity);
public HashMap(int initialCapacity, float loadFactor);
}
val point1 = new Point(y = 1)
```
Here we have to say `y = 1`.

While this keeps us from repeating ourselves, it's less than expressive.

Scala adds direct support for this:
Note that default parameters in Scala are not optional when called from Java code:

```tut
class HashMap[K,V](initialCapacity:Int = 16, loadFactor:Float = 0.75f) {
}

// Uses the defaults
val m1 = new HashMap[String,Int]

// initialCapacity 20, default loadFactor
val m2= new HashMap[String,Int](20)

// overriding both
val m3 = new HashMap[String,Int](20,0.8f)

// override only the loadFactor via
// named arguments
val m4 = new HashMap[String,Int](loadFactor = 0.8f)
// Point.scala
class Point(val x: Double = 0, val y: Double = 0)
```

Note how we can take advantage of *any* default value by using [named parameters]({{ site.baseurl }}/tutorials/tour/named-parameters.html).
```java
// Main.java
public class Main {
public static void main(String[] args) {
Point point = new Point(1); // does not compile
}
}
```