Skip to content

[docs/reference] more fixes in Markdown files #10860

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 2 commits into from
Dec 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ The precise steps for synthesizing an argument for a by-name context parameter o

1. If this search succeeds with expression `E`, and `E` contains references to `lv`, replace `E` by


```scala
{ given lv: T = E; lv }
```
Expand Down
60 changes: 30 additions & 30 deletions docs/docs/reference/contextual/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,40 @@ If such an instance `C` is found, the expression `e` is replaced by `C.apply(e)`
1. The `Predef` package contains "auto-boxing" conversions that map
primitive number types to subclasses of `java.lang.Number`. For instance, the
conversion from `Int` to `java.lang.Integer` can be defined as follows:
```scala
given int2Integer: Conversion[Int, java.lang.Integer] =
java.lang.Integer.valueOf(_)
```
```scala
given int2Integer: Conversion[Int, java.lang.Integer] =
java.lang.Integer.valueOf(_)
```

2. The "magnet" pattern is sometimes used to express many variants of a method. Instead of defining overloaded versions of the method, one can also let the method take one or more arguments of specially defined "magnet" types, into which various argument types can be converted. Example:
```scala
object Completions {
```scala
object Completions {

// The argument "magnet" type
enum CompletionArg {
case Error(s: String)
case Response(f: Future[HttpResponse])
case Status(code: Future[StatusCode])
}
object CompletionArg {
// The argument "magnet" type
enum CompletionArg {
case Error(s: String)
case Response(f: Future[HttpResponse])
case Status(code: Future[StatusCode])
}
object CompletionArg {

// conversions defining the possible arguments to pass to `complete`
// these always come with CompletionArg
// They can be invoked explicitly, e.g.
//
// CompletionArg.fromStatusCode(statusCode)
// conversions defining the possible arguments to pass to `complete`
// these always come with CompletionArg
// They can be invoked explicitly, e.g.
//
// CompletionArg.fromStatusCode(statusCode)

given fromString : Conversion[String, CompletionArg] = Error(_)
given fromFuture : Conversion[Future[HttpResponse], CompletionArg] = Response(_)
given fromStatusCode : Conversion[Future[StatusCode], CompletionArg] = Status(_)
}
import CompletionArg._
given fromString : Conversion[String, CompletionArg] = Error(_)
given fromFuture : Conversion[Future[HttpResponse], CompletionArg] = Response(_)
given fromStatusCode: Conversion[Future[StatusCode], CompletionArg] = Status(_)
}
import CompletionArg._

def complete[T](arg: CompletionArg) = arg match {
case Error(s) => ...
case Response(f) => ...
case Status(code) => ...
}
}
```
def complete[T](arg: CompletionArg) = arg match {
case Error(s) => ...
case Response(f) => ...
case Status(code) => ...
}
}
```
This setup is more complicated than simple overloading of `complete`, but it can still be useful if normal overloading is not available (as in the case above, since we cannot have two overloaded methods that take `Future[...]` arguments), or if normal overloading would lead to a combinatorial explosion of variants.
8 changes: 4 additions & 4 deletions docs/docs/reference/contextual/relationship-implicits.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout: doc-page
title: Relationship with Scala 2 Implicits
title: "Relationship with Scala 2 Implicits"
---

Many, but not all, of the new contextual abstraction features in Scala 3 can be mapped to Scala 2's implicits. This page gives a rundown on the relationships between new and old features.
Expand All @@ -11,7 +11,7 @@ Many, but not all, of the new contextual abstraction features in Scala 3 can be

Given instances can be mapped to combinations of implicit objects, classes and implicit methods.

1. Given instances without parameters are mapped to implicit objects. E.g.,
1. Given instances without parameters are mapped to implicit objects. For instance,

```scala
given intOrd: Ord[Int] with { ... }
Expand All @@ -23,7 +23,7 @@ Given instances can be mapped to combinations of implicit objects, classes and i
implicit object intOrd extends Ord[Int] { ... }
```

2. Parameterized givens are mapped to combinations of classes and implicit methods. E.g.,
2. Parameterized givens are mapped to combinations of classes and implicit methods. For instance,

```scala
given listOrd[T](using ord: Ord[T]): Ord[List[T]] with { ... }
Expand Down Expand Up @@ -70,7 +70,7 @@ The synthesized type names are formed from

1. the prefix `given_`,
2. the simple name(s) of the implemented type(s), leaving out any prefixes,
3. the simple name(s) of the toplevel argument type constructors to these types.
3. the simple name(s) of the top-level argument type constructors to these types.

Tuples are treated as transparent, i.e. a type `F[(X, Y)]` would get the synthesized name
`F_X_Y`. Directly implemented function types `A => B` are represented as `A_to_B`. Function types used as arguments to other type constructors are represented as `Function`.
Expand Down
14 changes: 7 additions & 7 deletions docs/docs/reference/dropped-features/package-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ implicit object Cops {
extension (x: C) def pair(y: C) = (x, y)
}
```
There may be several source files in a package containing such toplevel definitions, and source files can freely mix toplevel value, method, and type definitions with classes and objects.
There may be several source files in a package containing such top-level definitions, and source files can freely mix top-level value, method, and type definitions with classes and objects.

The compiler generates synthetic objects that wrap toplevel definitions falling into one of the following categories:
The compiler generates synthetic objects that wrap top-level definitions falling into one of the following categories:

- all pattern, value, method, and type definitions,
- implicit classes and objects,
- companion objects of opaque type aliases.

If a source file `src.scala` contains such toplevel definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package.
If a source file `src.scala` contains such top-level definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package.

**Note 1:** This means that the name of a source file containing wrapped toplevel definitions is relevant for binary compatibility. If the name changes, so does the name of the generated object and its class.
**Note 1:** This means that the name of a source file containing wrapped top-level definitions is relevant for binary compatibility. If the name changes, so does the name of the generated object and its class.

**Note 2:** A toplevel main method `def main(args: Array[String]): Unit = ...` is wrapped as any other method. If it appears
**Note 2:** A top-level main method `def main(args: Array[String]): Unit = ...` is wrapped as any other method. If it appears
in a source file `src.scala`, it could be invoked from the command line using a command like `scala src$package`. Since the
"program name" is mangled it is recommended to always put `main` methods in explicitly named objects.

**Note 3:** The notion of `private` is independent of whether a definition is wrapped or not. A `private` toplevel definition is always visible from everywhere in the enclosing package.
**Note 3:** The notion of `private` is independent of whether a definition is wrapped or not. A `private` top-level definition is always visible from everywhere in the enclosing package.

**Note 4:** If several toplevel definitions are overloaded variants with the same name,
**Note 4:** If several top-level definitions are overloaded variants with the same name,
they must all come from the same source file.
2 changes: 1 addition & 1 deletion docs/docs/reference/features-classification.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ These constructs replace existing constructs with the aim of making the language
- [Extension Methods](contextual/extension-methods.md) replace implicit classes with a clearer and simpler mechanism.
- [Opaque Type Aliases](other-new-features/opaques.md) replace most uses
of value classes while guaranteeing absence of boxing.
- [Toplevel definitions](dropped-features/package-objects.md) replace package objects, dropping syntactic boilerplate.
- [Top-level definitions](dropped-features/package-objects.md) replace package objects, dropping syntactic boilerplate.
- [Export clauses](other-new-features/export.md)
provide a simple and general way to express aggregation, which can replace the
previous facade pattern of package objects inheriting from classes.
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/metaprogramming/inline.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Inline methods can override other non-inline methods. The rules are as follows:
### Relationship to `@inline`

Scala 2 also defines a `@inline` annotation which is used as a hint
for the backend to inline. The `inline` modifier is a more powerful
for the backend to inline code. The `inline` modifier is a more powerful
option: Expansion is guaranteed instead of best effort,
it happens in the frontend instead of in the backend, and it also applies
to recursive methods.
Expand Down Expand Up @@ -293,7 +293,7 @@ val one: 1 = zero() + 1

## Inline Conditionals

If the condition of an if-then-else expressions is a constant expression then it simplifies to
An if-then-else expression whose condition is a constant expression can be simplified to
the selected branch. Prefixing an if-then-else expression with `inline` enforces that
the condition has to be a constant expression, and thus guarantees that the conditional will always
simplify.
Expand Down
3 changes: 3 additions & 0 deletions docs/docs/reference/metaprogramming/macros-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ private def dynamicPower(x: Double, n: Int): Double =
else x * dynamicPower(x, n - 1)
```

In the above, the method `.value` maps a constant expression of the type
`Expr[T]` to its value of the type `T`.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be not necessary, as .value indeed exists in stdlib.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It comes from @nicolasstucki's suggestion (see his comment in PR #10826).

Copy link
Contributor

@liufengyun liufengyun Dec 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change it to something like the following:

In the above, the method .value maps a constant expression of the type Expr[T] to its value of the type T.

Copy link
Contributor Author

@michelou michelou Dec 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (see below).

With the right extractors, the "AsFunction" conversion
that maps expressions over functions to functions over expressions can
be implemented in user code:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ FunctionN[K1, ..., Kn, R'] {
where the result type parameter `R'` is the least upper approximation of the
precise result type `R` without any reference to value parameters `x1, ..., xN`.

The syntax and sementics of anonymous dependent functions is identical to the
The syntax and semantics of anonymous dependent functions is identical to the
one of regular functions. Eta expansion is naturally generalized to produce
dependent function types for methods with dependent result types.

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/new-types/type-lambdas-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: "Type Lambdas - More Details"
Type ::= ... | TypeParamClause ‘=>>’ Type
TypeParamClause ::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’
TypeParam ::= {Annotation} (id [HkTypeParamClause] | ‘_’) TypeBounds
TypeBounds ::= [‘>:’ Type] [‘<:’ Type]
TypeBounds ::= [‘>:’ Type] [‘<:’ Type]
```

### Type Checking
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 match the two bound types `X`.
Here we have relied on [alpha renaming](https://en.wikipedia.org/wiki/Lambda_calculus#%CE%B1-conversion) 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 Down
4 changes: 2 additions & 2 deletions docs/docs/reference/other-new-features/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ It is a standard recommendation to prefer composition over inheritance. This is
So far, object oriented languages including Scala made it much easier to use inheritance than composition. Inheritance only requires an `extends` clause whereas composition required a verbose elaboration of a sequence of forwarders. So in that sense, OO languages are pushing
programmers to a solution that is often too powerful. Export clauses redress the balance. They make composition relationships as concise and easy to express as inheritance relationships. Export clauses also offer more flexibility than extends clauses since members can be renamed or omitted.

Export clauses also fill a gap opened by the shift from package objects to toplevel definitions. One occasionally useful idiom that gets lost in this shift is a package object inheriting from some class. The idiom is often used in a facade like pattern, to make members
of internal compositions available to users of a package. Toplevel definitions are not wrapped in a user-defined object, so they can't inherit anything. However, toplevel definitions can be export clauses, which supports the facade design pattern in a safer and
Export clauses also fill a gap opened by the shift from package objects to top-level definitions. One occasionally useful idiom that gets lost in this shift is a package object inheriting from some class. The idiom is often used in a facade like pattern, to make members
of internal compositions available to users of a package. Top-level definitions are not wrapped in a user-defined object, so they can't inherit anything. However, top-level definitions can be export clauses, which supports the facade design pattern in a safer and
more flexible way.

### Syntax changes:
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/other-new-features/indentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ if x < 0 then
```

Indentation tokens are only inserted in regions where newline statement separators are also inferred:
at the toplevel, inside braces `{...}`, but not inside parentheses `(...)`, patterns or types.
at the top-level, inside braces `{...}`, but not inside parentheses `(...)`, patterns or types.

### Optional Braces Around Template Bodies

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/other-new-features/matchable.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ extended by both `AnyVal` and `AnyRef`. Since `Matchable` is a supertype of ever
- Type parameters and abstract types that are only bounded by some
universal trait: Again, `Matchable` should be added as a bound.

Here is the hierarchy of toplevel classes and traits with their defined methods:
Here is the hierarchy of top-level classes and traits with their defined methods:

```scala
abstract class Any:
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/reference/other-new-features/opaques-details.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ defined on the underlying type. For instance,
x == y // uses Int equality for the comparison.
```

### Toplevel Opaque Types
### Top-level Opaque Types

An opaque type alias on the toplevel is transparent in all other toplevel definitions in the sourcefile where it appears, but is opaque in nested
An opaque type alias on the top-level is transparent in all other top-level definitions in the sourcefile where it appears, but is opaque in nested
objects and classes and in all other source files. Example:
```scala
// in test1.scala
Expand All @@ -91,7 +91,7 @@ object obj {
// in test2.scala
def z: String = x // error: found: A, required: String
```
This behavior becomes clear if one recalls that toplevel definitions are placed in their own synthetic object. For instance, the code in `test1.scala` would expand to
This behavior becomes clear if one recalls that top-level definitions are placed in their own synthetic object. For instance, the code in `test1.scala` would expand to
```scala
object test1$package {
opaque type A = String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ are treated automatically as transparent. Other traits are turned into transpare
by adding a `@transparentTrait` annotation. This annotation is defined in `scala.annotation`. It will be deprecated and phased out once Scala 2/3 interopability is no longer needed.

Typically, transparent traits are traits
that influence the implementation of inheriting classes and traits and that are not usually used as types by themselves. Two examples from the standard collection library:
that influence the implementation of inheriting classes and traits that are not usually used as types by themselves. Two examples from the standard collection library:

- `IterableOps`, which provides method implementations for an `Iterable`
- `StrictOptimizedSeqOps`, which optimises some of these implementations for
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ These constructs replace existing constructs with the aim of making the language
- [Extension Methods](contextual/extension-methods.md) replace implicit classes with a clearer and simpler mechanism.
- [Opaque type aliases](other-new-features/opaques.md) replace most uses
of value classes while guaranteeing absence of boxing.
- [Toplevel definitions](dropped-features/package-objects.md) replace package objects, dropping syntactic boilerplate.
- [Top-level definitions](dropped-features/package-objects.md) replace package objects, dropping syntactic boilerplate.
- [Export clauses](other-new-features/export.md)
provide a simple and general way to express aggregation, which can replace the
previous facade pattern of package objects inheriting from classes.
Expand Down