From 73e3ea1d2955b2cd48564d57b0889830b70d721b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Tue, 19 Jan 2021 09:55:24 +0100 Subject: [PATCH] more fixes in Markdown files --- .../changed-features/compiler-plugins.md | 2 +- .../changed-features/interpolation-escapes.md | 6 +- .../changed-features/main-functions.md | 4 +- .../reference/contextual/derivation-macro.md | 6 +- .../dropped-features/early-initializers.md | 4 ++ docs/docs/reference/metaprogramming/macros.md | 7 +- .../metaprogramming/tasty-inspect.md | 10 +-- .../other-new-features/safe-initialization.md | 4 +- .../reference/other-new-features/type-test.md | 65 ++++++++++++++----- docs/docs/reference/overview.md | 2 +- 10 files changed, 72 insertions(+), 38 deletions(-) diff --git a/docs/docs/reference/changed-features/compiler-plugins.md b/docs/docs/reference/changed-features/compiler-plugins.md index 3bfdaffdbf68..19f39ea759c4 100644 --- a/docs/docs/reference/changed-features/compiler-plugins.md +++ b/docs/docs/reference/changed-features/compiler-plugins.md @@ -42,7 +42,7 @@ pluginClass=dividezero.DivideZero This is different from `scalac` plugins that required a `scalac-plugin.xml` file. Starting from 1.1.5, `sbt` also supports Scala 3 compiler plugins. Please refer to the -`sbt` [documentation][2] for more information. +[`sbt` documentation][2] for more information. ## Writing a Standard Compiler Plugin diff --git a/docs/docs/reference/changed-features/interpolation-escapes.md b/docs/docs/reference/changed-features/interpolation-escapes.md index 75450b6f1d82..9a96f2a6d285 100644 --- a/docs/docs/reference/changed-features/interpolation-escapes.md +++ b/docs/docs/reference/changed-features/interpolation-escapes.md @@ -1,11 +1,11 @@ --- layout: doc-page -title: Escapes in interpolations +title: "Escapes in interpolations" --- -In Scala 2 there was no straightforward way to represent a single quote character `"` in a single quoted interpolation. A `\` character can't be used for that because interpolators themselves decide how to handle escaping, so the parser doesn't know whether the `"` should be escaped or used as a terminator. +In Scala 2 there is no straightforward way to represent a single quote character `"` in a single quoted interpolation. A `\` character can't be used for that because interpolators themselves decide how to handle escaping, so the parser doesn't know whether the `"` should be escaped or used as a terminator. -In Scala 3, you can use the `$` meta character of interpolations to escape a `"` character. +In Scala 3, we can use the `$` meta character of interpolations to escape a `"` character. Example: ```scala val inventor = "Thomas Edison" diff --git a/docs/docs/reference/changed-features/main-functions.md b/docs/docs/reference/changed-features/main-functions.md index 50aed8e4189f..b6897762797b 100644 --- a/docs/docs/reference/changed-features/main-functions.md +++ b/docs/docs/reference/changed-features/main-functions.md @@ -56,7 +56,7 @@ The Scala compiler generates a program from a `@main` method `f` as follows: - The class has a static method `main` with the usual signature. It takes an `Array[String]` as argument and returns `Unit`. - The generated `main` method calls method `f` with arguments converted using - methods in the [`scala.util.CommandLineParser` object](https://dotty.epfl.ch/api/scala/util/CommandLineParser$.html). + methods in the [`scala.util.CommandLineParser`](https://dotty.epfl.ch/api/scala/util/CommandLineParser$.html) object. For instance, the `happyBirthDay` method above would generate additional code equivalent to the following class: @@ -84,5 +84,5 @@ object happyBirthday extends App: ... ``` -The previous functionality of `App`, which relied on the "magic" [`DelayedInit`](../dropped-features/delayed-init.md) trait, is no longer available. `App` still exists in limited form for now, but it does not support command line arguments and will be deprecated in the future. If programs need to cross-build +The previous functionality of `App`, which relied on the "magic" [`DelayedInit`](../dropped-features/delayed-init.md) trait, is no longer available. [`App`](https://dotty.epfl.ch/api/scala/App.html) still exists in limited form for now, but it does not support command line arguments and will be deprecated in the future. If programs need to cross-build between Scala 2 and Scala 3, it is recommended to use an explicit `main` method with an `Array[String]` argument instead. diff --git a/docs/docs/reference/contextual/derivation-macro.md b/docs/docs/reference/contextual/derivation-macro.md index 46c1d66c573d..012da07abfee 100644 --- a/docs/docs/reference/contextual/derivation-macro.md +++ b/docs/docs/reference/contextual/derivation-macro.md @@ -1,6 +1,6 @@ --- layout: doc-page -title: How to write a type class `derived` method using macros +title: "How to write a type class `derived` method using macros" --- In the main [derivation](./derivation.md) documentation page, we explained the @@ -97,8 +97,8 @@ One additional difference with the body of `derived` here as opposed to the one with `inline` is that with macros we need to synthesize the body of the code during the macro-expansion time. That is the rationale behind the `eqProductBody` function. Assuming that we calculate the equality of two `Person`s defined with a case -class that holds a name of type `String` and an age of type `Int`, the equality -check we want to generate is the following: +class that holds a name of type [`String`](https://dotty.epfl.ch/api/scala/Predef$.html#String) +and an age of type `Int`, the equality check we want to generate is the following: ```scala true diff --git a/docs/docs/reference/dropped-features/early-initializers.md b/docs/docs/reference/dropped-features/early-initializers.md index 7b7179bf15cd..0f7b5717b197 100644 --- a/docs/docs/reference/dropped-features/early-initializers.md +++ b/docs/docs/reference/dropped-features/early-initializers.md @@ -4,8 +4,12 @@ title: "Dropped: Early Initializers" --- Early initializers of the form + ```scala class C extends { ... } with SuperClass ... ``` + have been dropped. They were rarely used, and mostly to compensate for the lack of [trait parameters](../other-new-features/trait-parameters.md), which are now directly supported in Scala 3. + +For more information, see [SLS ยง5.1.6](https://www.scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#early-definitions). diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 830abac3e08d..997252176fc3 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -16,10 +16,7 @@ schemes with the familiar string interpolation syntax. println(s"Hello, $name, here is the result of 1 + 1 = ${1 + 1}") ``` -In string interpolation we _quoted_ a string and then we _spliced_ into it, two -others. The first, `name`, is a reference to a value of type `string`, and the -second is an arithmetic expression that will be _evaluated_ followed by the -splicing of its string representation. +In string interpolation we _quoted_ a string and then we _spliced_ into it, two others. The first, `name`, is a reference to a value of type [`String`](https://dotty.epfl.ch/api/scala/Predef$.html#String), and the second is an arithmetic expression that will be _evaluated_ followed by the splicing of its string representation. Quotes and splices in this section allow us to treat code in a similar way, effectively supporting macros. The entry point for macros is an inline method @@ -86,7 +83,7 @@ and it takes types `T` to expressions of type `Type[T]`. Splicing takes expressions of type `Expr[T]` to expressions of type `T` and it takes expressions of type `Type[T]` to types `T`. -The two types can be defined in package `scala.quoted` as follows: +The two types can be defined in package [`scala.quoted`](https://dotty.epfl.ch/api/scala/quoted.html) as follows: ```scala package scala.quoted diff --git a/docs/docs/reference/metaprogramming/tasty-inspect.md b/docs/docs/reference/metaprogramming/tasty-inspect.md index 9b86a8650475..3547b8939a3d 100644 --- a/docs/docs/reference/metaprogramming/tasty-inspect.md +++ b/docs/docs/reference/metaprogramming/tasty-inspect.md @@ -22,17 +22,17 @@ import scala.quoted._ import scala.tasty.inspector._ class MyInspector extends TastyInspector: - protected def processCompilationUnit(using Quotes)(tree: quotes.reflect.Tree): Unit = - import quotes.reflect._ - // Do something with the tree + protected def processCompilationUnit(using Quotes)(tree: quotes.reflect.Tree): Unit = + import quotes.reflect._ + // Do something with the tree ``` Then the consumer can be instantiated with the following code to get the tree of the `foo/Bar.tasty` file. ```scala object Test: - def main(args: Array[String]): Unit = - new MyInspector().inspectTastyFiles("foo/Bar.tasty") + def main(args: Array[String]): Unit = + new MyInspector().inspectTastyFiles("foo/Bar.tasty") ``` Note that if we need to run the main (in the example below defined in an object called `Test`) after compilation we need to make the compiler available to the runtime: diff --git a/docs/docs/reference/other-new-features/safe-initialization.md b/docs/docs/reference/other-new-features/safe-initialization.md index bc035d3eb898..2d115745bb57 100644 --- a/docs/docs/reference/other-new-features/safe-initialization.md +++ b/docs/docs/reference/other-new-features/safe-initialization.md @@ -141,7 +141,9 @@ field points to an initialized object may not later point to an object under initialization. As an example, the following code will be rejected: ``` scala -trait Reporter { def report(msg: String): Unit } +trait Reporter: + def report(msg: String): Unit + class FileReporter(ctx: Context) extends Reporter: ctx.typer.reporter = this // ctx now reaches an uninitialized object val file: File = new File("report.txt") diff --git a/docs/docs/reference/other-new-features/type-test.md b/docs/docs/reference/other-new-features/type-test.md index e89592ff3e61..72323c4a0bc4 100644 --- a/docs/docs/reference/other-new-features/type-test.md +++ b/docs/docs/reference/other-new-features/type-test.md @@ -69,12 +69,14 @@ f[AnyRef, String]("acb")(using tt) ``` The compiler will synthesize a new instance of a type test if none is found in scope as: + ```scala new TypeTest[A, B]: def unapply(s: A): Option[s.type & B] = s match case s: B => Some(s) case _ => None ``` + If the type tests cannot be done there will be an unchecked warning that will be raised on the `case s: B =>` test. The most common `TypeTest` instances are the ones that take any parameters (i.e. `TypeTest[Any, T]`). @@ -106,11 +108,13 @@ Using `ClassTag` instances was unsound since classtags can check only the class `ClassTag` type tests are still supported but a warning will be emitted after 3.0. -## Examples +## Example -Given the following abstract definition of `Peano` numbers that provides `TypeTest[Nat, Zero]` and `TypeTest[Nat, Succ]` +Given the following abstract definition of Peano numbers that provides two given instances of types `TypeTest[Nat, Zero]` and `TypeTest[Nat, Succ]` ```scala +import scala.reflect._ + trait Peano: type Nat type Zero <: Nat @@ -125,25 +129,52 @@ trait Peano: def apply(nat: Nat): Succ def unapply(nat: Succ): Option[Nat] - given TypeTest[Nat, Zero] = typeTestOfZero - protected def typeTestOfZero: TypeTest[Nat, Zero] - given TypeTest[Nat, Succ] = typeTestOfSucc - protected def typeTestOfSucc: TypeTest[Nat, Succ] + given typeTestOfZero: TypeTest[Nat, Zero] + given typeTestOfSucc: TypeTest[Nat, Succ] ``` -it will be possible to write the following program +together with an implementation of Peano numbers based on type `Int` ```scala -val peano: Peano = ... -import peano._ -def divOpt(m: Nat, n: Nat): Option[(Nat, Nat)] = - n match - case Zero => None - case s @ Succ(_) => Some(safeDiv(m, s)) - -val two = Succ(Succ(Zero)) -val five = Succ(Succ(Succ(two))) -println(divOpt(five, two)) +object PeanoInt extends Peano: + type Nat = Int + type Zero = Int + type Succ = Int + + def safeDiv(m: Nat, n: Succ): (Nat, Nat) = (m / n, m % n) + + val Zero: Zero = 0 + + val Succ: SuccExtractor = new: + def apply(nat: Nat): Succ = nat + 1 + def unapply(nat: Succ) = Some(nat - 1) + + def typeTestOfZero: TypeTest[Nat, Zero] = new: + def unapply(x: Nat): Option[x.type & Zero] = + if x == 0 then Some(x) else None + + def typeTestOfSucc: TypeTest[Nat, Succ] = new: + def unapply(x: Nat): Option[x.type & Succ] = + if x > 0 then Some(x) else None +``` + +it is possible to write the following program + +```scala +@main def test = + import PeanoInt._ + + def divOpt(m: Nat, n: Nat): Option[(Nat, Nat)] = + n match + case Zero => None + case s @ Succ(_) => Some(safeDiv(m, s)) + + val two = Succ(Succ(Zero)) + val five = Succ(Succ(Succ(two))) + + println(divOpt(five, two)) // prints "Some((2,1))" + println(divOpt(two, five)) // prints "Some((0,2))" + println(divOpt(two, Zero)) // prints "None" ``` Note that without the `TypeTest[Nat, Succ]` the pattern `Succ.unapply(nat: Succ)` would be unchecked. diff --git a/docs/docs/reference/overview.md b/docs/docs/reference/overview.md index 415174ac2fe7..225385265c48 100644 --- a/docs/docs/reference/overview.md +++ b/docs/docs/reference/overview.md @@ -48,7 +48,7 @@ These constructs replace existing constructs with the aim of making the language instead of `new` expressions. `new` expressions stay around as a fallback for the cases where creator applications cannot be used. -With the exception of early initializers and old-style vararg patterns, all superseded constructs continue to be available in Scala 3.0. The plan is to deprecate and phase them out later. +With the exception of [early initializers](dropped-features/early-initializers.md) and old-style vararg patterns, all superseded constructs continue to be available in Scala 3.0. The plan is to deprecate and phase them out later. Value classes (superseded by opaque type aliases) are a special case. There are currently no deprecation plans for value classes, since we might bring them back in a more general form if they are supported natively by the JVM as is planned by [project Valhalla](https://openjdk.java.net/projects/valhalla/).