Skip to content

Commit cab2792

Browse files
committed
Merge branch 'gh-pages' of github.com:scala/scala.github.com into gh-pages
2 parents 0a5786b + 68b8bba commit cab2792

File tree

9 files changed

+1021
-4
lines changed

9 files changed

+1021
-4
lines changed

2.9.1/overviews/actors.md

Lines changed: 502 additions & 0 deletions
Large diffs are not rendered by default.

2.9.1/overviews/collections.md

Lines changed: 304 additions & 0 deletions
Large diffs are not rendered by default.

_includes/disqus.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<div id="disqus_thread"></div>
22
<script type="text/javascript">
3+
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
4+
var disqus_shortname = 'scalasip'; // required: replace example with your forum shortname
35

4-
var disqus_shortname = 'scala-lang'; // required: replace example with your forum shortname
5-
6+
/* * * DON'T EDIT BELOW THIS LINE * * */
67
(function() {
78
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
89
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
910
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
1011
})();
1112
</script>
13+
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
14+
<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>

_includes/frontpage-content.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<p>Read language improvement proposals, participate in discussions surrounding submitted proposals, or submit your own improvement proposal.</p>
3939

4040
<h3>Guides and Overviews <span class="label success">Some Available</span></h3>
41-
<p>Some guides, such as Martin Odersky's Collection's are already available. Others are currently being converted to markdown markup for inclusion here.</p>
41+
<p>Some guides, such as Martin Odersky's Collections Overview are already available. Others are currently being converted to markdown markup for inclusion here.</p>
4242

4343
<h3>Tutorials <span class="label success">Some Available</span></h3>
4444
<p>Some tutorials, such as the <em>Scala for Java Programmers</em> guide is already available. Others are currently being converted to markdown markup for inclusion here.</p>
61.6 KB
Loading
94.2 KB
Loading

resources/images/collections.png

21.2 KB
Loading

sips.new/.DS_Store

-6 KB
Binary file not shown.

sips.new/completed/_posts/2010-01-22-named-and-default-arguments.md

Lines changed: 209 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,212 @@ layout: sip
33
title: SID-1 Named and Default Arguments
44
---
55

6-
This was an older SID that can be found [here](http://www.scala-lang.org/sid/1)
6+
**Lukas Rytz**
7+
8+
## Introduction
9+
Methods taking multiple parameters of the same type are a source of mistakes which cannot be detected during compile time: exchanging two arguments of the same type does not yield an error, but can produce unexpected results. This problem can be avoided elegantly by using named arguments. Furthermore, named arguments improve the readability of method calls with a large number of arguments.
10+
11+
The second language feature discussed in this document, default arguments, in general does not depend on having named arguments. But combining the two features actually improves their usefulness, for instance it avoids the requirement of putting the parameters with defaults to the end of the parameter list of a method. For that reason, the two features are introduced together.
12+
13+
## Named Arguments
14+
15+
In Scala 2.8, method arguments can be specified in _named style_ using the same syntax as variable assignments:
16+
17+
def f[T](a: Int, b: T)
18+
f(b = getT(), a = getInt())
19+
20+
21+
The argument expressions are evaluated in call-site order, so in the above example `getT()` is executed before `getInt()`f. Mixing named and positional arguments is allowed as long as the positional part forms a prefix of the argument list:
22+
23+
f(0, b = "1") // valid
24+
f(b = "1", a = 0) // valid
25+
// f(b = "1", 0) // invalid, a positional after named argument
26+
// f(0, a = 1) // invalid, parameter ’a’ specified twice
27+
28+
29+
If an argument expression has the form `"x = expr"` and `x` is not a parameter name of the method, the argument is treated as an assignment expression to some variable `x`, i.e. the argument type is Unit. So the following example will continue to work as expected:
30+
31+
def twice(op: => Unit) = { op; op }
32+
var x = 1
33+
twice(x = x + 1)
34+
35+
It is an error if the expression `”x = expr”` can be interpreted as both a named argument (parameter name `x`) and an assignment (variable `x` in scope). If the expression is surrounded by an additonal set of parenthesis or braces, it is never treated as a named argument. Also, if the application argument is a block expression (as in `f{ arg }`), `arg` is never treated as a named argument.
36+
37+
def twice(op: => Unit) = { op; op }
38+
var op = 1
39+
// twice(op = op + 1) // error: reference to ‘op’ is ambiguous
40+
twice((op = op + 1)) // assignment, not a named argument
41+
twice({op = op + 1}) // assignment
42+
twice{ op = op + 1 } // assignment
43+
44+
### Integration with other features
45+
46+
The following list shows how named arguments interfere with other language features of Scala:
47+
48+
**By-Name Parameters** continue to work as expected when using named arguments. The expression is only (and repeatedly) evaluated when the body of the method accesses the parameter.
49+
50+
**Repeated Parameters** When an application uses named arguments, the repeated parameter has to be specified exactly once. Using the same parameter name multiple times is disallowed.
51+
52+
**Functional values** A functional value in Scala is an instance of a class which implements a method called apply. One can use the parameter names of that apply method for a named application. For functional values whose static type is scala.FunctionN, the parameter names of that apply method can be used.
53+
54+
val f1 = new { def apply(x: Int) = x + 1 }
55+
val f2 = (x: Int) => x + 1 // instance of Function1[Int, Int]
56+
f1(x = 2) // OK
57+
// f2(x = 2) // "error: not found: value x"
58+
f2(v1 = 2) // OK, ’v1’ is the parameter name in Function1
59+
60+
**Overriding** When a method is overridden (or an abstract method is implemented) in a subclass, the parameter names don’t have to be the same as in the superclass. For type-checking an application which uses named arguments, the static type of the method determines which names have to be used.
61+
62+
trait A { def f(a: Int): Int }
63+
class B extends A { def f(x: Int) = x }
64+
val a: A = new B
65+
a.f(a = 1) // OK
66+
67+
**Overloading Resolution** When a method application refers to an overloaded method, first the set of applicable alternatives is determined and then the most specific alternative is chosen (see [1], Chapter 6.25.3).
68+
69+
The presence of named argument influences the set of applicable alternatives, the argument types have to be matched against the corresponding parameter types based on the names. In the following example, the second alternative is applicable:
70+
71+
def f() // #1
72+
def f(a: Int, b: String) // #2
73+
f(b = "someString", a = 1) // using #2
74+
75+
If multiple alternatives are applicable, the most specific one is determined. This process is independent of the argument names used in a specific application and only looks at the method signature (for a detailed description, see [1], Chapter 6.25.3).
76+
77+
In the following example, both alternatives are applicable, but none of them is more specific than the other because the argument types are compared based on their position, not on the argument name:
78+
79+
def f(a: Int, b: String) // #1
80+
def f(b: Object, a: Int) // #2
81+
f(a = 1, b = "someString") // "error: ambiguous reference to
82+
// overloaded definition"
83+
84+
**Anonymous functions** The placeholder syntax syntax for creating anonymous functions is extended to work with named arguments.
85+
86+
def f(x: Int, y: String)
87+
val g1: Int => Int = f(y = "someString", x = _)
88+
val g2 = f(y = "someString", x = _: Int)
89+
90+
## Default Arguments
91+
92+
A method parameter with a default argument has the form `”p: T = expr”`, where `expr` is evaluated every time a method application uses the default argument. To use a default argument, the corresponding parameter has to be omitted in the method application.
93+
94+
def f(a: Int, b: String = "defaultString", c: Int = 5)
95+
f(1)
96+
f(1, "otherString")
97+
f(1, c = 10) // c needs to be specified as named argument
98+
99+
For every parameter with a default argument, a synthetic method which computes the default expression is generated. When a method application uses default arguments, the missing parameters are added to the argument list as calls to the corresponding synthetic methods.
100+
101+
def f(a: Int = 1, b: String)
102+
// generates a method: def f$default$1 = 1
103+
f(b = "3")
104+
// transformed to: f(b = "3", a = f$default$1)
105+
106+
A default argument may be an arbitrary expression. Since the scope of a parameter extends over all subsequent parameter lists (and the method body), default expressions can depend on parameters of preceding parameter lists (but not on other parameters in the same parameter list). Note that when using a default value which depends on earlier parameters, the actual arguments are used, not the default arguments.
107+
108+
def f(a: Int = 0)(b: Int = a + 1) = b // OK
109+
// def f(a: Int = 0, b: Int = a + 1) // "error: not found: value a"
110+
f(10)() // returns 11 (not 1)
111+
112+
A special expected type is used for type-checking the default argument `expr` of a method parameter `”x: T = expr”`: it is obtained by replacing all occurrences of type parameters of the method (type parameters of the class for constructors) with the undefined type. This allows specifying default arguments for polymorphic methods and classes:
113+
114+
def f[T](a: T = 1) = a
115+
f() // returns 1: Int
116+
f("s") // returns "s": String
117+
def g[T](a: T = 1, b: T = "2") = b
118+
g(a = "1") // OK, returns "2": String
119+
g(b = 2) // OK, returns 2: Int
120+
g() // OK, returns "2": Any
121+
// g[Int]() // "error: type mismatch; found: String, required: Int"
122+
class A[T](a: T = "defaultString")
123+
new A() // creates an instance of A[String]
124+
new A(1) // creates an instance of A[Int]
125+
126+
### Integration with other features
127+
128+
The following list shows how default arguments interfere with other language features of Scala:
129+
130+
**By-Name Parameters** Default arguments on by-name parameters work as expected. If an application does not specify a by-name parameter with a default argument, the default expression is evaluated every time the method body refers to that parameter.
131+
132+
**Repeated Parameters** It is not allowed to specify any default arguments in a parameter section which ends in a repeated parameter.
133+
134+
**Overriding** When a method with default arguments is overridden or implemented in a subclass, all defaults are inherited and available in the subclass. The subclass can also override default arguments and add new ones to parameters which don’t have a default in the superclass.
135+
136+
During type-checking, the static type is used to determine whether a parameter has a default value or not. At run-time, since the usage of a default is translated to a method call, the default value is determined by the dynamic type of the receiver object.
137+
138+
trait A { def f(a: Int = 1, b: Int): (Int, Int) }
139+
// B: inherit & add a default
140+
class B extends A { def f(a: Int, b: Int = 2) = (a, b) }
141+
// C: override a default
142+
class C extends A { def f(a: Int = 3, b: Int ) = (a, b) }
143+
val a1: A = new B
144+
val a2: A = new C
145+
// a1.f() // "error: unspecified parameter: value b"
146+
a2.f(b = 2) // returns (3, 2)
147+
148+
**Overloading** If there are multiple overloaded alternatives of a method, at most one is allowed to specify default arguments.
149+
150+
**Overloading Resolution** In a method application expression, when multiple overloaded alternatives are applicable, the alternative which use default arguments is never selected.
151+
152+
def f(a: Object) // #1
153+
def f(a: String, b: Int = 1) // #2
154+
f("str") // both are applicable, #1 is selected
155+
156+
**Case Classes** For every case class, a method named `”copy”` is now generated which allows to easily create modified copies of the class’s instances. 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.
157+
158+
case class A[T](a: T, b: Int) {
159+
// def copy[T’](a’: T’ = a, b’: Int = b): A[T’] =
160+
// new A[T’](a’, b’)
161+
}
162+
val a1: A[Int] = A(1, 2)
163+
val a2: A[String] = a1.copy(a = "someString")
164+
165+
The copy method is only added to a case class if no member named `”copy”` already exists in the class or in one of its parents. This implies that when a case class extends another case class, there will only be one copy method, namely the one from the lowest case class in the hierarchy.
166+
167+
**Implicit Parameters** It is allowed to specify default arguments on implicit parameters. These defaults are used in case no implicit value matching the parameter type can be found.
168+
169+
def f(implicit a: String = "value", y: Int = 0) = a +": "+ y
170+
implicit val s = "size"
171+
println(f) // prints "size: 0"
172+
173+
## Implementation
174+
175+
### Named arguments
176+
177+
When using named arguments, the argument order does not have to match the parameter order of the method definition. To evaluate the argument expressions in call-site order, the method application is transformed to a block in the following way:
178+
179+
class A {
180+
def f(a: Int, b: Int)(c: Int)
181+
}
182+
(new A).f(b = getB(), a = getA())(c = getC())
183+
// transformed to
184+
// {
185+
// val qual$1 = new A()
186+
// val x$1 = getB()
187+
// val x$2 = getA()
188+
// val x$3 = getC()
189+
// qual$1.f(x$2, x$1)(x$3)
190+
// }
191+
192+
### Default arguments
193+
194+
For every default argument expression the compiler generates a method computing that expression. These methods have deterministic names composed of the method name, the string `”$default$”` and a number indicating the parameter position. Each method is parametrized by the type parameters of the original method and by the value parameter sections preceding the corresponding parameter:
195+
196+
def f[T](a: Int = 1)(b: T = a + 1)(c: T = b)
197+
// generates:
198+
// def f$default$1[T]: Int = 1
199+
// def f$default$2[T](a: Int): Int = a + 1
200+
// def f$default$3[T](a: Int)(b: T): T = b
201+
202+
For constructor defaults, these methods are added to the companion object of the class (which is created if it does not exist). For other methods, the default methods are generated at the same location as the original method. Method calls which use default arguments are transformed into a block of the same form as described above for named arguments:
203+
204+
f()("str")()
205+
// transformed to:
206+
// {
207+
// val x$1 = f$default$1
208+
// val x$2 = "str"
209+
// val x$3 = f$default$3(x$1)(x$2)
210+
// f(x$1)(x$2)(x$3)
211+
// }
212+
213+
## References
214+
1. Odersky, M. _The Scala Language Specification, Version 2.7_. Available online at [http://www.scala-lang.org/docu/files/ScalaReference.pdf](http://www.scala-lang.org/docu/files/ScalaReference.pdf)

0 commit comments

Comments
 (0)