Skip to content

different documation improvments #8507

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 26 commits into from
Mar 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
72cef28
doc(adt): link to enum
robstoll Mar 11, 2020
d5bdeee
Merge pull request #3 from tegonal/doc-adt
robstoll Mar 11, 2020
a851af0
doc(enum): typo
robstoll Mar 11, 2020
d72417d
doc(dependent-fun): typo
robstoll Mar 8, 2020
8c67691
Merge pull request #4 from tegonal/doc-enum
robstoll Mar 11, 2020
bb6470f
Merge pull request #5 from tegonal/doc-dependent-fun
robstoll Mar 11, 2020
8d98f96
doc(match-type): fix type lambda syntax
robstoll Mar 7, 2020
13872b8
doc(match-type): 2nd fix type lambda syntax
robstoll Mar 7, 2020
1b3d830
Merge pull request #6 from tegonal/doc-match-type
robstoll Mar 11, 2020
01cb780
doc(match-type): fix type lambda syntax
robstoll Mar 7, 2020
57121cf
doc(type-lambda): use U instead of H for upper bound
robstoll Mar 6, 2020
ba8a518
doc(type-lambdas): variance is not supported
robstoll Mar 7, 2020
303353e
doc(type-lambda): typos
robstoll Mar 7, 2020
b7616ae
doc(type-lamba): remove superfluous `construct`
robstoll Mar 6, 2020
00a3987
doc(givens): mention thread safety
robstoll Mar 6, 2020
ac85b8b
doc(opaques-details): typo
robstoll Mar 6, 2020
870173c
doc(opaque type alias): revise text, remove workaround
robstoll Mar 2, 2020
47223c0
Merge pull request #8 from tegonal/doc-type-lambda-intro
robstoll Mar 11, 2020
771b0c0
Merge pull request #7 from tegonal/doc-opaque-detail
robstoll Mar 11, 2020
ed3bc4a
Merge pull request #9 from tegonal/doc-type-lambda-1
robstoll Mar 11, 2020
cb05b58
Merge pull request #10 from tegonal/doc-opaque-type-alias
robstoll Mar 11, 2020
dd9504a
Merge pull request #11 from tegonal/doc-type-lambda
robstoll Mar 11, 2020
0a52434
Merge pull request #12 from tegonal/doc-givens
robstoll Mar 11, 2020
6bc8d00
doc(opaque): remove reminder
robstoll Mar 12, 2020
97bc111
doc(givens): change given with using example
robstoll Mar 12, 2020
1582216
doc(opaque): replace `own type` with `abstract type`
robstoll Mar 12, 2020
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
13 changes: 7 additions & 6 deletions docs/docs/reference/contextual/givens.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ a given for the type `Ord[Int]` whereas `listOrd[T]` defines givens
for `Ord[List[T]]` for all types `T` that come with a given instance for `Ord[T]`
themselves. The `using` clause in `listOrd` defines a condition: There must be a
given of type `Ord[T]` for a given of type `List[Ord[T]]` to exist.
Such conditions are expanded by the compiler to context
parameters, which are explained in the [next section](./using-clauses.html).
Such conditions are expanded by the compiler to [context
parameters](./using-clauses.html).

## Anonymous Givens

Expand All @@ -57,14 +57,15 @@ given global as ExecutionContext = new ForkJoinPool()
This creates a given `global` of type `ExecutionContext` that resolves to the right
hand side `new ForkJoinPool()`.
The first time `global` is accessed, a new `ForkJoinPool` is created, which is then
returned for this and all subsequent accesses to `global`.
returned for this and all subsequent accesses to `global`. This operation is thread-safe.

Alias givens can be anonymous, e.g.
Alias givens can be anonymous as well, e.g.
```scala
given Position = enclosingTree.position
given (using outer: Context) as Context = outer.withOwner(currentOwner)
given (using config: Config) as Factory = MemoizingFactory(config)
```
An alias given can have type parameters and implicit parameters just like any other given,

An alias given can have type parameters and context parameters just like any other given,
but it can only implement a single type.

## Given Whitebox Macro Instances
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/reference/enums/adts.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ layout: doc-page
title: "Algebraic Data Types"
---

The `enum` concept is general enough to also support algebraic data
types (ADTs) and their generalized version (GADTs). Here's an example
The [`enum` concept](./enums.html) is general enough to also support algebraic data
types (ADTs) and their generalized version (GADTs). Here is an example
how an `Option` type can be represented as an ADT:

```scala
Expand Down Expand Up @@ -34,7 +34,7 @@ Note that the parent type of the `None` value is inferred as
`Option[Nothing]`. Generally, all covariant type parameters of the enum
class are minimized in a compiler-generated extends clause whereas all
contravariant type parameters are maximized. If `Option` was non-variant,
you'd need to give the extends clause of `None` explicitly.
you would need to give the extends clause of `None` explicitly.

As for normal enum values, the cases of an `enum` are all defined in
the `enum`s companion object. So it's `Option.Some` and `Option.None`
Expand Down
5 changes: 3 additions & 2 deletions docs/docs/reference/enums/enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ If you want to use the Scala-defined enums as Java enums, you can do so by exten
enum Color extends java.lang.Enum[Color] { case Red, Green, Blue }
```

The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum. There is no need to provide constructor arguments (as defined in the API docs) to `java.lang.Enum` when extending it – the compiler will generate them automatically.
The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum.
There is no need to provide constructor arguments (as defined in the Java API docs) to `java.lang.Enum` when extending it – the compiler will generate them automatically.

After defining `Color` like that, you can use like you would a Java enum:
After defining `Color` like that, you can use it like you would a Java enum:

```scala
scala> Color.Red.compareTo(Color.Green)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ FunctionN[K1, ..., Kn, R'] {
```

where the result type parameter `R'` is the least upper approximation of the
precise result type `R` without any referance to value parameters `x1, ..., xN`.
precise result type `R` without any reference to value parameters `x1, ..., xN`.

The syntax and sementics of anonymous dependent functions is identical to the
one of regular functions. Eta expansion is naturally generalized to produce
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/new-types/match-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ S match { P1 => T1 ... Pn => Tn }
```
is `Match(S, C1, ..., Cn) <: B` where each case `Ci` is of the form
```
[Xs] => P => T
[Xs] =>> P => T
```
Here, `[Xs]` is a type parameter clause of the variables bound in pattern `Pi`. If there are no bound type variables in a case, the type parameter clause is omitted and only the function type `P => T` is kept. So each case is either a unary function type or a type lambda over a unary function type.

Expand All @@ -68,7 +68,7 @@ We define match type reduction in terms of an auxiliary relation, `can-reduce`:
```
Match(S, C1, ..., Cn) can-reduce i, T'
```
if `Ci = [Xs] => P => T` and there are minimal instantiations `Is` of the type variables `Xs` such that
if `Ci = [Xs] =>> P => T` and there are minimal instantiations `Is` of the type variables `Xs` such that
```
S <: [Xs := Is] P
T' = [Xs := Is] T
Expand Down
10 changes: 5 additions & 5 deletions docs/docs/reference/new-types/type-lambdas-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ TypeBounds ::= [‘>:’ Type] [‘<:’ Type]

### Type Checking

A type lambda such as `[X] =>> F[X]` defines a function from types to types. The parameter(s) may carry bounds and variance annotations.
If a parameter is bounded, as in `[X >: L <: H] =>> F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `H`.
Only the upper bound `H` can be F-bounded, i.e. `X` can appear in it.
A type lambda such as `[X] =>> F[X]` defines a function from types to types. The parameter(s) may carry bounds.
If a parameter is bounded, as in `[X >: L <: U] =>> F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `U`.
Only the upper bound `U` can be F-bounded, i.e. `X` can appear in it.

## Subtyping Rules

Expand All @@ -31,7 +31,7 @@ Then `TL1 <: TL2`, if
`L1 <: L2` and `U2 <: U1`),
- `R1 <: R2`

Here we have relied on alpha renaming to bring match the two bound types `X`.
Here we have relied on alpha renaming to match the two bound types `X`.

A partially applied type constructor such as `List` is assumed to be equivalent to
its eta expansion. I.e, `List = [X] =>> List[X]`. This allows type constructors to be compared with type lambdas.
Expand All @@ -46,7 +46,7 @@ is regarded as a shorthand for an unparameterized definition with a type lambda
```scala
type T = [X] =>> R
```
If the a type definition carries `+` or `-` variance annotations,
If the type definition carries `+` or `-` variance annotations,
it is checked that the variance annotations are satisfied by the type lambda.
For instance,
```scala
Expand Down
6 changes: 2 additions & 4 deletions docs/docs/reference/new-types/type-lambdas.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ a type definition.
[X, Y] =>> Map[Y, X]
```

For instance, the type above defines a binary type constructor, which
constructor maps arguments `X` and `Y` to `Map[Y, X]`. Type parameters
of type lambdas can have bounds but they cannot carry `+` or `-` variance
annotations.
For instance, the type above defines a binary type constructor, which maps arguments `X` and `Y` to `Map[Y, X]`.
Type parameters of type lambdas can have bounds but they cannot carry `+` or `-` variance annotations.

[More details](./type-lambdas-spec.md)
2 changes: 1 addition & 1 deletion docs/docs/reference/other-new-features/opaques-details.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ where the lower bound `L` and the upper bound `U` may be missing, in which case
Inside the scope of the alias definition, the alias is transparent: `T` is treated
as a normal alias of `R`. Outside its scope, the alias is treated as the abstract type
```scala
type T >: L <: U`
type T >: L <: U
```
A special case arises if the opaque type is defined in an object. Example:
```
Expand Down
31 changes: 15 additions & 16 deletions docs/docs/reference/other-new-features/opaques.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ object Logarithms {

object Logarithm {

// These are the ways to lift to the logarithm type
// These are the two ways to lift to the Logarithm type

def apply(d: Double): Logarithm = math.log(d)

def safe(d: Double): Option[Logarithm] =
Expand All @@ -28,19 +29,19 @@ object Logarithms {
}
```

This introduces `Logarithm` as a new type, which is implemented as `Double` but is different from it. The fact that `Logarithm` is the same as `Double` is only known in the scope where
`Logarithm` is defined which in this case is object `Logarithms`.

The public API of `Logarithm` consists of the `apply` and `safe` methods that convert from doubles to `Logarithm` values, an extension method `toDouble` that converts the other way,
and operations `+` and `*` on logarithm values. The implementations of these functions
type-check because within object `Logarithms`, the type `Logarithm` is just an alias of `Double`.
This introduces `Logarithm` as a new abstract type, which is implemented as `Double`.
The fact that `Logarithm` is the same as `Double` is only known in the scope where
`Logarithm` is defined which in the above example corresponds to the object `Logarithms`.
Or in other words, within the scope it is treated as type alias, but this is opaque to the outside world
where in consequence `Logarithm` is seen as an abstract type and has nothing to do with `Double`.

Outside its scope, `Logarithm` is treated as a new abstract type. So the
following operations would be valid because they use functionality implemented in the `Logarithm` object.
The public API of `Logarithm` consists of the `apply` and `safe` methods defined in the companion object.
They convert from `Double`s to `Logarithm` values. Moreover, a collective extension `logarithmOps` provides the extension methods `toDouble` that converts the other way,
and operations `+` and `*` on `Logarithm` values.
The following operations would be valid because they use functionality implemented in the `Logarithms` object.

```scala
import Logarithms._
import Predef.{any2stringadd => _, _}
import Logarithms.Logarithm

val l = Logarithm(1.0)
val l2 = Logarithm(2.0)
Expand All @@ -54,11 +55,9 @@ But the following operations would lead to type errors:
val d: Double = l // error: found: Logarithm, required: Double
val l2: Logarithm = 1.0 // error: found: Double, required: Logarithm
l * 2 // error: found: Int(2), required: Logarithm
l / l2 // error: `/` is not a member fo Logarithm
l / l2 // error: `/` is not a member of Logarithm
```

Aside: the `any2stringadd => _` import suppression is necessary since otherwise the universal `+` operation in `Predef` would take precedence over the `+` extension method in `logarithmOps`. We plan to resolve this wart by eliminating `any2stringadd`.

### Bounds For Opaque Type Aliases

Opaque type aliases can also come with bounds. Example:
Expand All @@ -81,7 +80,7 @@ object Access {
val ReadOrWrite: PermissionChoice = Read | Write
}
```
The `Access` object defines three opaque types:
The `Access` object defines three opaque type aliases:

- `Permission`, representing a single permission,
- `Permissions`, representing a set of permissions with the meaning "all of these permissions granted",
Expand All @@ -98,7 +97,7 @@ Because of that, the `|` extension method in `Access` does not cause infinite re
Also, the definition of `ReadWrite` must use `|`,
even though an equivalent definition outside `Access` would use `&`.

All three opaque types have the same underlying representation type `Int`. The
All three opaque type aliases have the same underlying representation type `Int`. The
`Permission` type has an upper bound `Permissions & PermissionChoice`. This makes
it known outside the `Access` object that `Permission` is a subtype of the other
two types. Hence, the following usage scenario type-checks.
Expand Down