Skip to content

Commit 69a1f05

Browse files
committed
more fixed in Markdown files
1 parent 46290f9 commit 69a1f05

28 files changed

+109
-89
lines changed

docs/docs/reference/changed-features/structural-types-spec.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The standard library defines a universal marker trait `Selectable` in the packag
2020
trait Selectable extends Any
2121
```
2222

23-
An implementation of `Selectable` that relies on Java reflection is
23+
An implementation of `Selectable` that relies on [Java reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html) is
2424
available in the standard library: `scala.reflect.Selectable`. Other
2525
implementations can be envisioned for platforms where Java reflection
2626
is not available.

docs/docs/reference/changed-features/structural-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Besides `selectDynamic`, a `Selectable` class sometimes also defines a method `a
7474

7575
## Using Java Reflection
7676

77-
Structural types can also be accessed using Java reflection. Example:
77+
Structural types can also be accessed using [Java reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html). Example:
7878
```scala
7979
type Closeable = {
8080
def close(): Unit

docs/docs/reference/changed-features/vararg-patterns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ The change to the grammar is:
3636

3737
## Compatibility considerations
3838

39-
To enable smooth cross compilation between Scala 2 and Scala 3, Dotty will
39+
To enable smooth cross compilation between Scala 2 and Scala 3, the compiler will
4040
accept both the old and the new syntax. Under the `-source 3.1` setting, an error
4141
will be emitted when the old syntax is encountered. They will be enabled by
4242
default in version 3.1 of the language.

docs/docs/reference/contextual/derivation-macro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ true
113113
&& Eq[Int].eqv(x.productElement(1), y.productElement(1))
114114
```
115115

116-
### Calling the derived method inside the macro
116+
## Calling the derived method inside the macro
117117

118118
Following the rules in [Macros](../metaprogramming/toc.md) we create two methods.
119119
One that hosts the top-level splice `eqv` and one that is the implementation.

docs/docs/reference/contextual/derivation.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ Note the following properties of `Mirror` types,
130130
+ The kinds of `MirroredType` and `MirroredElemTypes` match the kind of the data type the mirror is an instance for.
131131
This allows `Mirrors` to support ADTs of all kinds.
132132
+ There is no distinct representation type for sums or products (ie. there is no `HList` or `Coproduct` type as in
133-
Scala 2 versions of shapeless). Instead the collection of child types of a data type is represented by an ordinary,
133+
Scala 2 versions of Shapeless). Instead the collection of child types of a data type is represented by an ordinary,
134134
possibly parameterized, tuple type. Scala 3's metaprogramming facilities can be used to work with these tuple types
135135
as-is, and higher level libraries can be built on top of them.
136136
+ For both product and sum types, the elements of `MirroredElemTypes` are arranged in definition order (i.e. `Branch[T]`
137137
precedes `Leaf[T]` in `MirroredElemTypes` for `Tree` because `Branch` is defined before `Leaf` in the source file).
138-
This means that `Mirror.Sum` differs in this respect from shapeless's generic representation for ADTs in Scala 2,
138+
This means that `Mirror.Sum` differs in this respect from Shapeless's generic representation for ADTs in Scala 2,
139139
where the constructors are ordered alphabetically by name.
140140
+ The methods `ordinal` and `fromProduct` are defined in terms of `MirroredMonoType` which is the type of kind-`*`
141141
which is obtained from `MirroredType` by wildcarding its type parameters.
@@ -164,7 +164,7 @@ Type class authors will most likely use higher level derivation or generic progr
164164
described above and Scala 3's general metaprogramming features is provided below. It is not anticipated that type class
165165
authors would normally implement a `derived` method in this way, however this walkthrough can be taken as a guide for
166166
authors of the higher level derivation libraries that we expect typical type class authors will use (for a fully
167-
worked out example of such a library, see [shapeless 3](https://github.com/milessabin/shapeless/tree/shapeless-3)).
167+
worked out example of such a library, see [Shapeless 3](https://github.com/milessabin/shapeless/tree/shapeless-3)).
168168

169169
#### How to write a type class `derived` method using low level mechanisms
170170

@@ -243,6 +243,7 @@ def eqProduct[T](p: Mirror.ProductOf[T], elems: List[Eq[_]]): Eq[T] =
243243
```
244244

245245
Pulling this all together we have the following complete implementation,
246+
[//]: # see tests/run/typeclass-derivation-doc-example.scala
246247

247248
```scala
248249
import scala.deriving._
@@ -259,7 +260,6 @@ trait Eq[T] {
259260
}
260261

261262
object Eq {
262-
263263
given Eq[Int] with {
264264
def eqv(x: Int, y: Int) = x == y
265265
}
@@ -303,7 +303,7 @@ enum Opt[+T] derives Eq {
303303
case Nn
304304
}
305305

306-
object Test extends App {
306+
@main def Test() =
307307
import Opt._
308308
val eqoi = summon[Eq[Opt[Int]]]
309309
assert(eqoi.eqv(Sm(23), Sm(23)))
@@ -329,7 +329,7 @@ Alternative approaches can be taken to the way that `derived` methods can be def
329329
inlined variants using Scala 3 macros, whilst being more involved for type class authors to write than the example
330330
above, can produce code for type classes like `Eq` which eliminate all the abstraction artefacts (eg. the `Lists` of
331331
child instances in the above) and generate code which is indistinguishable from what a programmer might write by hand.
332-
As a third example, using a higher level library such as shapeless the type class author could define an equivalent
332+
As a third example, using a higher level library such as Shapeless the type class author could define an equivalent
333333
`derived` method as,
334334

335335
```scala
@@ -340,12 +340,15 @@ given eqSum[A](using inst: => K0.CoproductInstances[Eq, A]): Eq[A] {
340340
}
341341

342342
given eqProduct[A](using inst: K0.ProductInstances[Eq, A]): Eq[A] {
343-
def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean)(
344-
[t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => Complete(!eqt.eqv(t0, t1))(false)(true)
345-
)
343+
def eqv(x: A, y: A): Boolean =
344+
inst.foldLeft2(x, y)(true: Boolean)(
345+
[t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) =>
346+
Complete(!eqt.eqv(t0, t1))(false)(true)
347+
)
346348
}
347349

348-
inline def derived[A](using gen: K0.Generic[A]) as Eq[A] = gen.derive(eqSum, eqProduct)
350+
inline def derived[A](using gen: K0.Generic[A]) as Eq[A] =
351+
gen.derive(eqSum, eqProduct)
349352
```
350353

351354
The framework described here enables all three of these approaches without mandating any of them.
@@ -411,6 +414,6 @@ written these casts will never fail.
411414
As mentioned, however, the compiler-provided mechanism is intentionally very low level and it is anticipated that
412415
higher level type class derivation and generic programming libraries will build on this and Scala 3's other
413416
metaprogramming facilities to hide these low-level details from type class authors and general users. Type class
414-
derivation in the style of both shapeless and Magnolia are possible (a prototype of shapeless 3, which combines
415-
aspects of both shapeless 2 and Magnolia has been developed alongside this language feature) as is a more aggressively
417+
derivation in the style of both Shapeless and Magnolia are possible (a prototype of Shapeless 3, which combines
418+
aspects of both Shapeless 2 and Magnolia has been developed alongside this language feature) as is a more aggressively
416419
inlined style, supported by Scala 3's new quote/splice macro and inlining facilities.

docs/docs/reference/contextual/motivation.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ title: "Overview"
88
Scala's implicits are its most distinguished feature. They are _the_ fundamental way to abstract over context. They represent a unified paradigm with a great variety of use cases, among them: implementing type classes, establishing context, dependency injection, expressing capabilities, computing new types and proving relationships between them.
99

1010
Following Haskell, Scala was the second popular language to have some form of implicits. Other languages have followed suit. E.g [Rust's traits](https://doc.rust-lang.org/rust-by-example/trait.html) or [Swift's protocol extensions](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID521). Design proposals are also on the table for Kotlin as [compile time dependency resolution](https://github.com/Kotlin/KEEP/blob/e863b25f8b3f2e9b9aaac361c6ee52be31453ee0/proposals/compile-time-dependency-resolution.md), for C# as [Shapes and Extensions](https://github.com/dotnet/csharplang/issues/164)
11-
or for F# as [Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md). Implicits are also a common feature of theorem provers such as Coq or [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html).
11+
or for F# as [Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md). Implicits are also a common feature of theorem provers such as [Coq](https://coq.inria.fr/refman/language/extensions/implicit-arguments.html) or [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html).
1212

1313
Even though these designs use widely different terminology, they are all variants of the core idea of _term inference_. Given a type, the compiler synthesizes a "canonical" term that has that type. Scala embodies the idea in a purer form than most other languages: An implicit parameter directly leads to an inferred argument term that could also be written down explicitly. By contrast, type class based designs are less direct since they hide term inference behind some form of type classification and do not offer the option of writing the inferred quantities (typically, dictionaries) explicitly.
1414

@@ -30,12 +30,14 @@ Particular criticisms are:
3030
3. The syntax of implicit definitions is too minimal. It consists of a single modifier, `implicit`, that can be attached to a large number of language constructs. A problem with this for newcomers is that it conveys mechanism instead of intent. For instance, a type class instance is an implicit object or val if unconditional and an implicit def with implicit parameters referring to some class if conditional. This describes precisely what the implicit definitions translate to -- just drop the `implicit` modifier, and that's it! But the cues that define intent are rather indirect and can be easily misread, as demonstrated by the definitions of `i1` and `i2` above.
3131

3232
4. The syntax of implicit parameters also has shortcomings. While implicit _parameters_ are designated specifically, arguments are not. Passing an argument to an implicit parameter looks like a regular application `f(arg)`. This is problematic because it means there can be confusion regarding what parameter gets instantiated in a call. For instance, in
33+
3334
```scala
3435
def currentMap(implicit ctx: Context): Map[String, Int]
3536
```
36-
one cannot write `currentMap("abc")` since the string "abc" is taken as explicit argument to the implicit `ctx` parameter. One has to write `currentMap.apply("abc")` instead, which is awkward and irregular. For the same reason, a method definition can only have one implicit parameter section and it must always come last. This restriction not only reduces orthogonality, but also prevents some useful program constructs, such as a method with a regular parameter whose type depends on an implicit value. Finally, it's also a bit annoying that implicit parameters must have a name, even though in many cases that name is never referenced.
3737

38-
5. Implicits pose challenges for tooling. The set of available implicits depends on context, so command completion has to take context into account. This is feasible in an IDE but docs like ScalaDoc that are based static web pages can only provide an approximation. Another problem is that failed implicit searches often give very unspecific error messages, in particular if some deeply recursive implicit search has failed. Note that the Scala 3 compiler has already made a lot of progress in the error diagnostics area. If a recursive search fails some levels down, it shows what was constructed and what is missing. Also, it suggests imports that can bring missing implicits in scope.
38+
one cannot write `currentMap("abc")` since the string `"abc"` is taken as explicit argument to the implicit `ctx` parameter. One has to write `currentMap.apply("abc")` instead, which is awkward and irregular. For the same reason, a method definition can only have one implicit parameter section and it must always come last. This restriction not only reduces orthogonality, but also prevents some useful program constructs, such as a method with a regular parameter whose type depends on an implicit value. Finally, it's also a bit annoying that implicit parameters must have a name, even though in many cases that name is never referenced.
39+
40+
5. Implicits pose challenges for tooling. The set of available implicits depends on context, so command completion has to take context into account. This is feasible in an IDE but tools like [Scaladoc](https://docs.scala-lang.org/overviews/scaladoc/overview.html) that are based on static web pages can only provide an approximation. Another problem is that failed implicit searches often give very unspecific error messages, in particular if some deeply recursive implicit search has failed. Note that the Scala 3 compiler has already made a lot of progress in the error diagnostics area. If a recursive search fails some levels down, it shows what was constructed and what is missing. Also, it suggests imports that can bring missing implicits in scope.
3941

4042
None of the shortcomings is fatal, after all implicits are very widely used, and many libraries and applications rely on them. But together, they make code using implicits a lot more cumbersome and less clear than it could be.
4143

docs/docs/reference/contextual/multiversal-equality.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ class Box[T](x: T) derives CanEqual
9797
By the usual rules of [type class derivation](./derivation.md),
9898
this generates the following `CanEqual` instance in the companion object of `Box`:
9999
```scala
100-
given [T, U](using CanEqual[T, U]): CanEqual[Box[T], Box[U]] = CanEqual.derived
100+
given [T, U](using CanEqual[T, U]): CanEqual[Box[T], Box[U]] =
101+
CanEqual.derived
101102
```
102103
That is, two boxes are comparable with `==` or `!=` if their elements are. Examples:
103104
```scala

docs/docs/reference/contextual/relationship-implicits.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ mirroring the definition syntax. E.g, `max(2, 3)(using IntOrd)`.
9595
Scala 2 uses normal applications `max(2, 3)(IntOrd)` instead. The Scala 2 syntax has some inherent ambiguities and restrictions which are overcome by the new syntax. For instance, multiple implicit parameter lists are not available in the old syntax, even though they can be simulated using auxiliary objects in the "Aux" pattern.
9696

9797
The `summon` method corresponds to `implicitly` in Scala 2.
98-
It is precisely the same as the `the` method in Shapeless.
98+
It is precisely the same as the `the` method in [Shapeless](https://github.com/milessabin/shapeless).
9999
The difference between `summon` (or `the`) and `implicitly` is
100100
that `summon` can return a more precise type than the type that was
101101
asked for.
@@ -129,7 +129,7 @@ Abstract extension methods in traits that are implemented in given instances hav
129129

130130
### Type Class Derivation
131131

132-
Type class derivation has no direct counterpart in the Scala 2 language. Comparable functionality can be achieved by macro-based libraries such as Shapeless, Magnolia, or scalaz-deriving.
132+
Type class derivation has no direct counterpart in the Scala 2 language. Comparable functionality can be achieved by macro-based libraries such as [Shapeless](https://github.com/milessabin/shapeless), [Magnolia](https://propensive.com/opensource/magnolia), or [scalaz-deriving](https://github.com/scalaz/scalaz-deriving).
133133

134134
### Context Function Types
135135

docs/docs/reference/contextual/type-classes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ This way, we could define an instance of `Functor` for the `List` type:
7878
```scala
7979
given Functor[List] with
8080
def map[A, B](x: List[A], f: A => B): List[B] =
81-
x.map(f) // List already has a `map` method
81+
x.map(f) // List already has a `map` method
8282
```
8383

8484
With this `given` instance in scope, everywhere a `Functor` is expected, the compiler will accept a `List` to be used.
@@ -112,6 +112,7 @@ given Functor[List] with
112112
extension [A, B](xs: List[A])
113113
def map(f: A => B): List[B] =
114114
xs.map(f) // List already has a `map` method
115+
115116
```
116117

117118
It simplifies the `assertTransformation` method:

docs/docs/reference/enums/desugarEnums.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ some terminology and notational conventions:
2525

2626
The desugaring rules imply that class cases are mapped to case classes, and singleton cases are mapped to `val` definitions.
2727

28-
There are nine desugaring rules. Rule (1) desugar enum definitions. Rules
28+
There are nine desugaring rules. Rule (1) desugars enum definitions. Rules
2929
(2) and (3) desugar simple cases. Rules (4) to (6) define `extends` clauses for cases that
3030
are missing them. Rules (7) to (9) define how such cases with `extends` clauses
3131
map into `case class`es or `val`s.
@@ -176,11 +176,12 @@ If `E` contains at least one simple case, its companion object will define in ad
176176
follows.
177177

178178
```scala
179-
private def $new(_$ordinal: Int, $name: String) = new E with runtime.EnumValue {
180-
def ordinal = _$ordinal
181-
override def productPrefix = $name // if not overridden in `E`
182-
override def toString = $name // if not overridden in `E`
183-
}
179+
private def $new(_$ordinal: Int, $name: String) =
180+
new E with runtime.EnumValue {
181+
def ordinal = _$ordinal
182+
override def productPrefix = $name // if not overridden in `E`
183+
override def toString = $name // if not overridden in `E`
184+
}
184185
```
185186

186187
The anonymous class also implements the abstract `Product` methods that it inherits from `Enum`.

docs/docs/reference/features-classification.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Being new features, existing code migrates without changes. To be sure, sometime
162162

163163
## Metaprogramming
164164

165-
The following constructs together aim to put metaprogramming in Scala on a new basis. So far, metaprogramming was achieved by a combination of macros and libraries such as Shapeless that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3.
165+
The following constructs together aim to put metaprogramming in Scala on a new basis. So far, metaprogramming was achieved by a combination of macros and libraries such as [Shapeless](https://github.com/milessabin/shapeless) that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3.
166166

167167
It's worth noting that macros were never included in the Scala 2 language specification and were so far made available only under an `-experimental` flag. This has not prevented their widespread usage.
168168

docs/docs/reference/metaprogramming/erased-terms-spec.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ layout: doc-page
33
title: "Erased Terms Spec"
44
---
55

6-
# Implementation
6+
## Implementation
77

8-
## Rules
8+
### Rules
99

1010
1. The `erased` modifier can appear:
1111
* At the start of a parameter block of a method, function or class

docs/docs/reference/metaprogramming/inline.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def factorial(n: BigInt): BigInt = {
8989
}
9090
```
9191

92-
Note, that the by-value parameter `msg` is evaluated only once, per the usual Scala
92+
Note that the by-value parameter `msg` is evaluated only once, per the usual Scala
9393
semantics, by binding the value and reusing the `msg` through the body of
9494
`factorial`. Also, note the special handling of the assignment to the private var
9595
`indent`. It is achieved by generating a setter method `def inline$indent_=` and calling it instead.

0 commit comments

Comments
 (0)