summaryrefslogtreecommitdiff
path: root/06-basic-declarations-and-definitions.md
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-03-11 17:20:13 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-03-11 17:37:41 -0700
commit9fb82769f4cdc51198a7252e117a2a3828e7b00e (patch)
tree7807ea639db4f19cee2abbfa85a19061e31ba320 /06-basic-declarations-and-definitions.md
parent19ab789a37ce429550ee8ca6e20f00111ff76b54 (diff)
downloadscala-9fb82769f4cdc51198a7252e117a2a3828e7b00e.tar.gz
scala-9fb82769f4cdc51198a7252e117a2a3828e7b00e.tar.bz2
scala-9fb82769f4cdc51198a7252e117a2a3828e7b00e.zip
github markdown: use ###### for examples
Diffstat (limited to '06-basic-declarations-and-definitions.md')
-rw-r--r--06-basic-declarations-and-definitions.md526
1 files changed, 272 insertions, 254 deletions
diff --git a/06-basic-declarations-and-definitions.md b/06-basic-declarations-and-definitions.md
index 5d8f6aee78..b8eb226d3d 100644
--- a/06-basic-declarations-and-definitions.md
+++ b/06-basic-declarations-and-definitions.md
@@ -160,24 +160,26 @@ val $x$ = $e$ match { case $p$ => $x$ }
$e$ match { case $p$ => ()}
```
-(@) The following are examples of value definitions
+###### Example
- ```
- val pi = 3.1415
- val pi: Double = 3.1415 // equivalent to first definition
- val Some(x) = f() // a pattern definition
- val x :: xs = mylist // an infix pattern definition
- ```
+The following are examples of value definitions
- The last two definitions have the following expansions.
+```
+val pi = 3.1415
+val pi: Double = 3.1415 // equivalent to first definition
+val Some(x) = f() // a pattern definition
+val x :: xs = mylist // an infix pattern definition
+```
+
+The last two definitions have the following expansions.
- ```
- val x = f() match { case Some(x) => x }
+```
+val x = f() match { case Some(x) => x }
- val x$\$$ = mylist match { case x :: xs => (x, xs) }
- val x = x$\$$._1
- val xs = x$\$$._2
- ```
+val x$\$$ = mylist match { case x :: xs => (x, xs) }
+val x = x$\$$._1
+val xs = x$\$$._2
+```
The name of any declared or defined value may not end in `_=`.
@@ -253,35 +255,37 @@ The template then has these getter and setter functions as
members, whereas the original variable cannot be accessed directly as
a template member.
-(@) The following example shows how _properties_ can be
- simulated in Scala. It defines a class `TimeOfDayVar` of time
- values with updatable integer fields representing hours, minutes, and
- seconds. Its implementation contains tests that allow only legal
- values to be assigned to these fields. The user code, on the other
- hand, accesses these fields just like normal variables.
-
- ```
- class TimeOfDayVar {
- private var h: Int = 0
- private var m: Int = 0
- private var s: Int = 0
-
- def hours = h
- def hours_= (h: Int) = if (0 <= h && h < 24) this.h = h
- else throw new DateError()
-
- def minutes = m
- def minutes_= (m: Int) = if (0 <= m && m < 60) this.m = m
- else throw new DateError()
-
- def seconds = s
- def seconds_= (s: Int) = if (0 <= s && s < 60) this.s = s
- else throw new DateError()
- }
- val d = new TimeOfDayVar
- d.hours = 8; d.minutes = 30; d.seconds = 0
- d.hours = 25 // throws a DateError exception
- ```
+###### Example
+
+The following example shows how _properties_ can be
+simulated in Scala. It defines a class `TimeOfDayVar` of time
+values with updatable integer fields representing hours, minutes, and
+seconds. Its implementation contains tests that allow only legal
+values to be assigned to these fields. The user code, on the other
+hand, accesses these fields just like normal variables.
+
+```
+class TimeOfDayVar {
+ private var h: Int = 0
+ private var m: Int = 0
+ private var s: Int = 0
+
+ def hours = h
+ def hours_= (h: Int) = if (0 <= h && h < 24) this.h = h
+ else throw new DateError()
+
+ def minutes = m
+ def minutes_= (m: Int) = if (0 <= m && m < 60) this.m = m
+ else throw new DateError()
+
+ def seconds = s
+ def seconds_= (s: Int) = if (0 <= s && s < 60) this.s = s
+ else throw new DateError()
+}
+val d = new TimeOfDayVar
+d.hours = 8; d.minutes = 30; d.seconds = 0
+d.hours = 25 // throws a DateError exception
+```
A variable declaration `var $x_1 , \ldots , x_n$: $T$` is a shorthand for the
@@ -342,51 +346,55 @@ That is, the type $T$ in a type alias `type $t$[$\mathit{tps}\,$] = $T$` may not
refer directly or indirectly to the name $t$. It is also an error if
an abstract type is directly or indirectly its own upper or lower bound.
-(@) The following are legal type declarations and definitions:
+###### Example
+
+The following are legal type declarations and definitions:
- ```
- type IntList = List[Integer]
- type T <: Comparable[T]
- type Two[A] = Tuple2[A, A]
- type MyCollection[+X] <: Iterable[X]
- ```
+```
+type IntList = List[Integer]
+type T <: Comparable[T]
+type Two[A] = Tuple2[A, A]
+type MyCollection[+X] <: Iterable[X]
+```
- The following are illegal:
+The following are illegal:
- ```
- type Abs = Comparable[Abs] // recursive type alias
+```
+type Abs = Comparable[Abs] // recursive type alias
- type S <: T // S, T are bounded by themselves.
- type T <: S
+type S <: T // S, T are bounded by themselves.
+type T <: S
- type T >: Comparable[T.That] // Cannot select from T.
- // T is a type, not a value
- type MyCollection <: Iterable // Type constructor members must explicitly
- // state their type parameters.
- ```
+type T >: Comparable[T.That] // Cannot select from T.
+ // T is a type, not a value
+type MyCollection <: Iterable // Type constructor members must explicitly
+ // state their type parameters.
+```
If a type alias `type $t$[$\mathit{tps}\,$] = $S$` refers to a class type
$S$, the name $t$ can also be used as a constructor for
objects of type $S$.
-(@) The `Predef` object contains a definition which establishes `Pair`
- as an alias of the parameterized class `Tuple2`:
+###### Example
- ```
- type Pair[+A, +B] = Tuple2[A, B]
- object Pair {
- def apply[A, B](x: A, y: B) = Tuple2(x, y)
- def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
- }
- ```
+The `Predef` object contains a definition which establishes `Pair`
+as an alias of the parameterized class `Tuple2`:
+
+```
+type Pair[+A, +B] = Tuple2[A, B]
+object Pair {
+ def apply[A, B](x: A, y: B) = Tuple2(x, y)
+ def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
+}
+```
- As a consequence, for any two types $S$ and $T$, the type
- `Pair[$S$, $T\,$]` is equivalent to the type `Tuple2[$S$, $T\,$]`.
- `Pair` can also be used as a constructor instead of `Tuple2`, as in:
+As a consequence, for any two types $S$ and $T$, the type
+`Pair[$S$, $T\,$]` is equivalent to the type `Tuple2[$S$, $T\,$]`.
+`Pair` can also be used as a constructor instead of `Tuple2`, as in:
- ```
- val x: Pair[Int, String] = new Pair(1, "abc")
- ```
+```
+val x: Pair[Int, String] = new Pair(1, "abc")
+```
## Type Parameters
@@ -428,28 +436,29 @@ A type constructor parameter adds a nested type parameter clause to the type par
The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter $t$) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of $t$. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a ‘_’, which is nowhere visible.
-(@) Here are some well-formed type parameter clauses:
+###### Example
+Here are some well-formed type parameter clauses:
- ```
- [S, T]
- [@specialized T, U]
- [Ex <: Throwable]
- [A <: Comparable[B], B <: A]
- [A, B >: A, C >: A <: B]
- [M[X], N[X]]
- [M[_], N[_]] // equivalent to previous clause
- [M[X <: Bound[X]], Bound[_]]
- [M[+X] <: Iterable[X]]
- ```
+```
+[S, T]
+[@specialized T, U]
+[Ex <: Throwable]
+[A <: Comparable[B], B <: A]
+[A, B >: A, C >: A <: B]
+[M[X], N[X]]
+[M[_], N[_]] // equivalent to previous clause
+[M[X <: Bound[X]], Bound[_]]
+[M[+X] <: Iterable[X]]
+```
- The following type parameter clauses are illegal:
+The following type parameter clauses are illegal:
- ```
- [A >: A] // illegal, `A' has itself as bound
- [A <: B, B <: C, C <: A] // illegal, `A' has itself as bound
- [A, B, C >: A <: B] // illegal lower bound `A' of `C' does
- // not conform to upper bound `B'.
- ```
+```
+[A >: A] // illegal, `A' has itself as bound
+[A <: B, B <: C, C <: A] // illegal, `A' has itself as bound
+[A, B, C >: A <: B] // illegal lower bound `A' of `C' does
+ // not conform to upper bound `B'.
+```
## Variance Annotations
@@ -502,75 +511,78 @@ References to the type parameters in
checked for their variance position. In these members the type parameter may
appear anywhere without restricting its legal variance annotations.
-(@) The following variance annotation is legal.
-
- ```
- abstract class P[+A, +B] {
- def fst: A; def snd: B
- }
- ```
-
- With this variance annotation, type instances
- of $P$ subtype covariantly with respect to their arguments.
- For instance,
-
- ```
- P[IOException, String] <: P[Throwable, AnyRef]
- ```
-
- If the members of $P$ are mutable variables,
- the same variance annotation becomes illegal.
-
- ```
- abstract class Q[+A, +B](x: A, y: B) {
- var fst: A = x // **** error: illegal variance:
- var snd: B = y // `A', `B' occur in invariant position.
- }
- ```
-
- If the mutable variables are object-private, the class definition
- becomes legal again:
-
- ```
- abstract class R[+A, +B](x: A, y: B) {
- private[this] var fst: A = x // OK
- private[this] var snd: B = y // OK
- }
- ```
-
-(@) The following variance annotation is illegal, since $a$ appears
- in contravariant position in the parameter of `append`:
-
- ```
- abstract class Sequence[+A] {
- def append(x: Sequence[A]): Sequence[A]
- // **** error: illegal variance:
- // `A' occurs in contravariant position.
- }
- ```
-
- The problem can be avoided by generalizing the type of `append`
- by means of a lower bound:
-
- ```
- abstract class Sequence[+A] {
- def append[B >: A](x: Sequence[B]): Sequence[B]
- }
- ```
-
-(@) Here is a case where a contravariant type parameter is useful.
-
- ```
- abstract class OutputChannel[-A] {
- def write(x: A): Unit
- }
- ```
-
- With that annotation, we have that
- `OutputChannel[AnyRef]` conforms to `OutputChannel[String]`.
- That is, a
- channel on which one can write any object can substitute for a channel
- on which one can write only strings.
+###### Example
+The following variance annotation is legal.
+
+```
+abstract class P[+A, +B] {
+ def fst: A; def snd: B
+}
+```
+
+With this variance annotation, type instances
+of $P$ subtype covariantly with respect to their arguments.
+For instance,
+
+```
+P[IOException, String] <: P[Throwable, AnyRef]
+```
+
+If the members of $P$ are mutable variables,
+the same variance annotation becomes illegal.
+
+```
+abstract class Q[+A, +B](x: A, y: B) {
+ var fst: A = x // **** error: illegal variance:
+ var snd: B = y // `A', `B' occur in invariant position.
+}
+```
+
+If the mutable variables are object-private, the class definition
+becomes legal again:
+
+```
+abstract class R[+A, +B](x: A, y: B) {
+ private[this] var fst: A = x // OK
+ private[this] var snd: B = y // OK
+}
+```
+
+###### Example
+
+The following variance annotation is illegal, since $a$ appears
+in contravariant position in the parameter of `append`:
+
+```
+abstract class Sequence[+A] {
+ def append(x: Sequence[A]): Sequence[A]
+ // **** error: illegal variance:
+ // `A' occurs in contravariant position.
+}
+```
+
+The problem can be avoided by generalizing the type of `append`
+by means of a lower bound:
+
+```
+abstract class Sequence[+A] {
+ def append[B >: A](x: Sequence[B]): Sequence[B]
+}
+```
+
+###### Example: Here is a case where a contravariant type parameter is useful.
+
+```
+abstract class OutputChannel[-A] {
+ def write(x: A): Unit
+}
+```
+
+With that annotation, we have that
+`OutputChannel[AnyRef]` conforms to `OutputChannel[String]`.
+That is, a
+channel on which one can write any object can substitute for a channel
+on which one can write only strings.
## Function Declarations and Definitions
@@ -636,21 +648,22 @@ parameter clauses, as well as the method return type and the function body, if
they are given. Both type parameter names and value parameter names must
be pairwise distinct.
-(@) In the method
+###### Example
+In the method
- ```
- def compare[T](a: T = 0)(b: T = a) = (a == b)
- ```
+```
+def compare[T](a: T = 0)(b: T = a) = (a == b)
+```
- the default expression `0` is type-checked with an undefined expected
- type. When applying `compare()`, the default value `0` is inserted
- and `T` is instantiated to `Int`. The methods computing the default
- arguments have the form:
+the default expression `0` is type-checked with an undefined expected
+type. When applying `compare()`, the default value `0` is inserted
+and `T` is instantiated to `Int`. The methods computing the default
+arguments have the form:
- ```
- def compare$\$$default$\$$1[T]: Int = 0
- def compare$\$$default$\$$2[T](a: T): T = a
- ```
+```
+def compare$\$$default$\$$1[T]: Int = 0
+def compare$\$$default$\$$2[T](a: T): T = a
+```
### By-Name Parameters
@@ -673,14 +686,15 @@ classes for which a `val` prefix is implicitly generated. The
by-name modifier is also disallowed for
[implicit parameters](#implicit-parameters).
-(@) The declaration
+###### Example
+The declaration
- ```
- def whileLoop (cond: => Boolean) (stat: => Unit): Unit
- ```
+```
+def whileLoop (cond: => Boolean) (stat: => Unit): Unit
+```
- indicates that both parameters of `whileLoop` are evaluated using
- call-by-name.
+indicates that both parameters of `whileLoop` are evaluated using
+call-by-name.
### Repeated Parameters
@@ -710,44 +724,45 @@ that application is taken to be
It is not allowed to define any default arguments in a parameter section
with a repeated parameter.
-(@) The following method definition computes the sum of the squares of a
- variable number of integer arguments.
+###### Example
+The following method definition computes the sum of the squares of a
+variable number of integer arguments.
- ```
- def sum(args: Int*) = {
- var result = 0
- for (arg <- args) result += arg * arg
- result
- }
- ```
+```
+def sum(args: Int*) = {
+ var result = 0
+ for (arg <- args) result += arg * arg
+ result
+}
+```
- The following applications of this method yield `0`, `1`,
- `6`, in that order.
+The following applications of this method yield `0`, `1`,
+`6`, in that order.
- ```
- sum()
- sum(1)
- sum(1, 2, 3)
- ```
+```
+sum()
+sum(1)
+sum(1, 2, 3)
+```
- Furthermore, assume the definition:
+Furthermore, assume the definition:
- ```
- val xs = List(1, 2, 3)
- ```
+```
+val xs = List(1, 2, 3)
+```
- The following application of method `sum` is ill-formed:
+The following application of method `sum` is ill-formed:
- ```
- sum(xs) // ***** error: expected: Int, found: List[Int]
- ```
+```
+sum(xs) // ***** error: expected: Int, found: List[Int]
+```
- By contrast, the following application is well formed and yields again
- the result `6`:
+By contrast, the following application is well formed and yields again
+the result `6`:
- ```
- sum(xs: _*)
- ```
+```
+sum(xs: _*)
+```
### Procedures
@@ -769,27 +784,28 @@ and the equals sign are omitted; its defining expression must be a block.
E.g., `def $f$($\mathit{ps}$) {$\mathit{stats}$}` is equivalent to
`def $f$($\mathit{ps}$): Unit = {$\mathit{stats}$}`.
-(@) Here is a declaration and a definition of a procedure named `write`:
+###### Example
+Here is a declaration and a definition of a procedure named `write`:
- ```
- trait Writer {
- def write(str: String)
- }
- object Terminal extends Writer {
- def write(str: String) { System.out.println(str) }
- }
- ```
+```
+trait Writer {
+ def write(str: String)
+}
+object Terminal extends Writer {
+ def write(str: String) { System.out.println(str) }
+}
+```
- The code above is implicitly completed to the following code:
+The code above is implicitly completed to the following code:
- ```
- trait Writer {
- def write(str: String): Unit
- }
- object Terminal extends Writer {
- def write(str: String): Unit = { System.out.println(str) }
- }
- ```
+```
+trait Writer {
+ def write(str: String): Unit
+}
+object Terminal extends Writer {
+ def write(str: String): Unit = { System.out.println(str) }
+}
+```
### Method Return Type Inference
@@ -803,19 +819,20 @@ right-hand side of $m$ can be determined, which is then taken as the
return type of $m$. Note that $R$ may be different from $R'$, as long
as $R$ conforms to $R'$.
-(@) Assume the following definitions:
+###### Example
+Assume the following definitions:
- ```
- trait I {
- def factorial(x: Int): Int
- }
- class C extends I {
- def factorial(x: Int) = if (x == 0) 1 else x * factorial(x - 1)
- }
- ```
+```
+trait I {
+ def factorial(x: Int): Int
+}
+class C extends I {
+ def factorial(x: Int) = if (x == 0) 1 else x * factorial(x - 1)
+}
+```
- Here, it is OK to leave out the result type of `factorial`
- in `C`, even though the method is recursive.
+Here, it is OK to leave out the result type of `factorial`
+in `C`, even though the method is recursive.
@@ -901,23 +918,24 @@ An import clause with multiple import expressions
sequence of import clauses
`import $p_1$.$I_1$; $\ldots$; import $p_n$.$I_n$`.
-(@) Consider the object definition:
+###### Example
+Consider the object definition:
- ```
- object M {
- def z = 0, one = 1
- def add(x: Int, y: Int): Int = x + y
- }
- ```
- Then the block
+```
+object M {
+ def z = 0, one = 1
+ def add(x: Int, y: Int): Int = x + y
+}
+```
- ```
- { import M.{one, z => zero, _}; add(zero, one) }
- ```
+Then the block
- is equivalent to the block
+```
+{ import M.{one, z => zero, _}; add(zero, one) }
+```
- ```
- { M.add(M.z, M.one) }
- ```
+is equivalent to the block
+```
+{ M.add(M.z, M.one) }
+```