Skip to content

Commit 31657a8

Browse files
committed
Apply limit22.md
1 parent e64ee9e commit 31657a8

File tree

5 files changed

+70
-27
lines changed

5 files changed

+70
-27
lines changed

docs/_spec/03-types.md

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,27 @@ G[S, Int] // illegal: S constrains its parameter to
217217
SimpleType ::= ‘(’ Types ‘)’
218218
```
219219

220-
A _tuple type_ ´(T_1 , ... , T_n)´ is an alias for the class `scala.Tuple´n´[´T_1´, ... , ´T_n´]`, where ´n \geq 2´.
220+
A _tuple type_ ´(T_1, ..., T_n)´ where ´n \geq 2´ is an alias for the type `´T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple`.
221+
222+
Note:
223+
`(´T´)` is just the type ´T´, and not `´T´ *: scala.EmptyTuple`.
224+
`()` is not a valid type, and not `scala.EmptyTuple`.
225+
226+
If ´n \leq 22´, the type `´T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple` is both a subtype and a supertype of tuple class `scala.Tuple´_n´[´T_1´, ..., ´T_n´]`.
221227

222228
Tuple classes are case classes whose fields can be accessed using selectors `_1`, ..., `_n`.
223-
Their functionality is abstracted in a corresponding `Product` trait.
229+
Their functionality is abstracted in the corresponding `scala.Product_´n´` trait.
224230
The _n_-ary tuple class and product trait are defined at least as follows in the standard Scala library (they might also add other methods and implement other traits).
225231

226232
```scala
227233
case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´)
228234
extends Product´_n´[´T_1´, ..., ´T_n´]
229235

230-
trait Product´_n´[+´T_1´, ..., +´T_n´] {
236+
trait Product´_n´[+´T_1´, ..., +´T_n´] extends Product:
231237
override def productArity = ´n´
232238
def _1: ´T_1´
233239
...
234240
def _n: ´T_n´
235-
}
236241
```
237242

238243
### Annotated Types
@@ -329,25 +334,26 @@ FunctionArgs ::= InfixType
329334
| ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’
330335
```
331336

332-
The type ´(T_1, ..., T_n) \Rightarrow U´ represents the set of function values that take arguments of types ´T_1, ..., Tn´ and yield results of type ´U´.
333-
In the case of exactly one argument type ´T \Rightarrow U´ is a shorthand for ´(T) \Rightarrow U´.
334-
An argument type of the form ´\Rightarrow T´ represents a [call-by-name parameter](04-basic-declarations-and-definitions.html#by-name-parameters) of type ´T´.
337+
The type ´(T_1, ..., T_n) \Rightarrow R´ represents the set of function values that take arguments of types ´T_1, ..., Tn´ and yield results of type ´R´.
338+
The case of exactly one argument type ´T \Rightarrow R´ is a shorthand for ´(T) \Rightarrow R´.
339+
An argument type of the form ´\Rightarrow T´ represents a [call-by-name parameter](04-basic-declarations-and-definitions.md#by-name-parameters) of type ´T´.
335340

336-
Function types associate to the right, e.g. ´S \Rightarrow T \Rightarrow U´ is the same as ´S \Rightarrow (T \Rightarrow U)´.
341+
Function types associate to the right, e.g. ´S \Rightarrow T \Rightarrow R´ is the same as ´S \Rightarrow (T \Rightarrow R)´.
342+
343+
Function types are [covariant](04-basic-declarations-and-definitions.md#variance-annotations) in their result type and [contravariant](04-basic-declarations-and-definitions.md#variance-annotations) in their argument types.
337344

338345
Function types are shorthands for class types that define an `apply` method.
339-
Specifically, the ´n´-ary function type ´(T_1 , \ldots , T_n) \Rightarrow U´ is a shorthand for the class type `Function´_n´[´T_1´ , … , ´T_n´, ´U´]`.
340-
Such class types are defined in the Scala library for ´n´ between 0 and 22 as follows.
346+
Specifically, the ´n´-ary function type ´(T_1, ..., T_n) \Rightarrow R´ is a shorthand for the class type `Function´_n´[´T_1´, ..., ´T_n´, ´R´]`.
347+
In particular ´() \Rightarrow R´ is a shorthand for class type `Function´_0´[´R´]`.
348+
349+
Such class types behave as if they were instances of the following trait:
341350

342351
```scala
343-
package scala
344-
trait Function´_n´[-´T_1´, ..., -´T_n´, +´U´] {
345-
def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´U´
346-
override def toString = "<function>"
347-
}
352+
trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]:
353+
def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´R´
348354
```
349355

350-
Hence, function types are [covariant](04-basic-declarations-and-definitions.html#variance-annotations) in their result type and contravariant in their argument types.
356+
Their exact supertype and implementation can be consulted in the [function classes section](./12-the-scala-standard-library.md#the-function-classes) of the standard library page in this document.
351357

352358
#### Wildcard Types
353359

docs/_spec/06-expressions.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,15 @@ Type applications can be omitted if [local type inference](#local-type-inference
381381
```ebnf
382382
SimpleExpr ::= ‘(’ [Exprs] ‘)’
383383
```
384+
A _tuple expression_ `(´e_1´, ..., ´e_n´)` where ´n \geq 2´ is equivalent to the expression `´e_1´ *: ... *: ´e_n´ *: scala.EmptyTuple`.
384385

385-
A _tuple expression_ `(´e_1´, ..., ´e_n´)` is an alias for the class instance creation `scala.Tuple´n´(´e_1´, ..., ´e_n´)`, where ´n \geq 2´.
386-
The empty tuple `()` is the unique value of type `scala.Unit`.
386+
Note:
387+
As calls to `*:` are slow, a more efficient translation is free to be implemented.
388+
For example, `(´e_1´, ´e_2´)` could be translated to `scala.Tuple2(´e_1´, ´e_2´)`, which is indeed equivalent to `´e_1´ *: ´e_2´ *: scala.EmptyTuple`.
389+
390+
Note:
391+
The expression `(´e_1´)` is not equivalent to `´e_1´ *: scala.EmptyTuple`, but instead a regular parenthesized expression.
392+
The expression `()` is not an alias for `scala.EmptyTuple`, but instead the unique value of type `scala.Unit`.
387393

388394
## Instance Creation Expressions
389395

@@ -909,6 +915,9 @@ Binding ::= (id | ‘_’) [‘:’ Type]
909915
The anonymous function of arity ´n´, `(´x_1´: ´T_1, ..., x_n´: ´T_n´) => e` maps parameters ´x_i´ of types ´T_i´ to a result given by expression ´e´.
910916
The scope of each formal parameter ´x_i´ is ´e´.
911917
Formal parameters must have pairwise distinct names.
918+
Type bindings can be omitted, in which case the compiler will attempt to infer valid bindings.
919+
920+
Note: `() => ´e´` defines a nullary function (´n´ = 0), and not for example `(_: Unit) => ´e´`.
912921

913922
In the case of a single untyped formal parameter, `(´x\,´) => ´e´` can be abbreviated to `´x´ => ´e´`.
914923
If an anonymous function `(´x´: ´T\,´) => ´e´` with a single typed parameter appears as the result expression of a block, it can be abbreviated to `´x´: ´T´ => e`.

docs/_spec/08-pattern-matching.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,15 @@ This is further discussed [here](#pattern-sequences).
185185
SimplePattern ::= ‘(’ [Patterns] ‘)’
186186
```
187187

188-
A _tuple pattern_ `(´p_1´, ..., ´p_n´)` is an alias for the constructor pattern `scala.Tuple´n´(´p_1´, ..., ´p_n´)`, where ´n \geq 2´. The empty tuple `()` is the unique value of type `scala.Unit`.
188+
A _tuple pattern_ `(´p_1´, ..., ´p_n´)` where ´n \geq 2´ is equivalent to `´p_1´ *: ... *: ´p_n´ *: scala.EmptyTuple`.
189+
190+
Note:
191+
`()` is equivalent to `_: scala.Unit`, and not `scala.EmptyTuple`.
192+
`(´pat´)` is a pattern matching ´pat´, and not `´pat´ *: scala.EmptyTuple`.
193+
194+
Note:
195+
As such patterns with `*:` are slow, a more efficient translation is free to be implemented.
196+
For example, `(´p_1´, ´p_2´)` could be translated to `scala.Tuple2(´p_1´, ´p_2´)`, which is indeed equivalent to `´p_1´ *: ´p_2´ *: scala.EmptyTuple`.
189197

190198
### Extractor Patterns
191199

docs/_spec/12-the-scala-standard-library.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ def + (that: Any): String
288288

289289
which concatenates its left operand with the textual representation of its right operand.
290290

291+
<!-- TODO: re-add ? with explanations of: EmptyTuple, *:, NonEmptyTuple, TupleXXL
291292
### The `Tuple` classes
292293
293294
Scala defines tuple classes `Tuple´n´` for ´n = 2, ..., 22´.
@@ -299,20 +300,36 @@ case class Tuple´n´[+T_1, ..., +T_n](_1: T_1, ..., _´n´: T_´n´) {
299300
def toString = "(" ++ _1 ++ "," ++ ... ++ "," ++ _´n´ ++ ")"
300301
}
301302
```
302-
303+
-->
303304
### The `Function` Classes
304305

305-
Scala defines function classes `Function´n´` for ´n = 1 , \ldots , 22´.
306-
These are defined as follows.
306+
For each class type `Function´n´` where ´n = 0, ..., 22´, Scala defines the following function class:
307307

308308
```scala
309309
package scala
310-
trait Function´n´[-T_1, ..., -T_´n´, +R] {
311-
def apply(x_1: T_1, ..., x_´n´: T_´n´): R
312-
def toString = "<function>"
313-
}
310+
trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]:
311+
def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´R´
312+
override def toString = "<function´_n´>"
313+
def curried: ´T_1´ => ... => ´T_n´ => R = ...
314+
def tupled: ((´T_1´, ..., ´T_n´)) => R = ...
315+
```
316+
317+
For function types `Function´n´` where ´n > 22´, Scala defines a unique function class:
318+
319+
```scala
320+
package scala
321+
trait FunctionXXL:
322+
def apply(xs: IArray[Object]): Object
323+
override def toString = "<functionXXL>"
314324
```
315325

326+
There is no loss of type safety, as the internal representation is still `Function´n´` for all ´n´.
327+
However this means methods `curried` and `tupled` are not available on functions with more than 22 parameters.
328+
329+
The implicitly imported [`Predef`](#the-predef-object) object defines the name
330+
`Function` as an alias of `Function1`.
331+
332+
<!-- TODO: Remove below ? -->
316333
The `PartialFunction` subclass of `Function1` represents functions that (indirectly) specify their domain.
317334
Use the `isDefined` method to query whether the partial function is defined for a given input (i.e., whether the input is part of the function's domain).
318335

@@ -322,7 +339,10 @@ class PartialFunction[-A, +B] extends Function1[A, B] {
322339
}
323340
```
324341

325-
The implicitly imported [`Predef`](#the-predef-object) object defines the name `Function` as an alias of `Function1`.
342+
### Trait `Product`
343+
<!-- TODO: Move somewhere else ? -->
344+
<!-- TODO: Could not find more info on which non-Product methods case class automatically define -->
345+
All case classes automatically extend the `Product` trait (and generate synthetic methods to conform to it) (but not `Product´n´`), and define a `_´n´` method for each of their arguments.
326346

327347
### Class `Array`
328348

0 commit comments

Comments
 (0)