diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index 6179c57098..4c65c0b734 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -149,9 +149,9 @@ See [this]({{ site.baseurl }}/tutorials/FAQ/initialization-order.html). See the [Scala 2.13 Collections Guide](https://docs.scala-lang.org/overviews/collections-2.13/introduction.html). -### What are context bounds (`[T : Foo]`)? +### What are context bounds? -It's syntactic sugar for an `implicit` parameter of type `Foo[T]`. +It's syntactic sugar for a context parameter (an `implicit` parameter in Scala 2, or a `using` parameter in Scala 3). More details in this [Stack Overflow answer](https://stackoverflow.com/a/4467012). diff --git a/_overviews/scala3-book/ca-context-bounds.md b/_overviews/scala3-book/ca-context-bounds.md index 7d4faa3c4d..b95482a25e 100644 --- a/_overviews/scala3-book/ca-context-bounds.md +++ b/_overviews/scala3-book/ca-context-bounds.md @@ -1,20 +1,14 @@ --- title: Context Bounds type: section -description: This page demonstrates Context Bounds in Scala 3. +description: This page demonstrates Context Bounds in Scala. languages: [zh-cn] num: 61 previous-page: ca-given-using-clauses next-page: ca-given-imports --- - -{% comment %} -- TODO: define "context parameter" -- TODO: define "synthesized" and "synthesized arguments" -{% endcomment %} - -In many situations the name of a _context parameter_ doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters. +In many situations the name of a [context parameter]({% link _overviews/scala3-book/ca-given-using-clauses.md %}#using-clauses) doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters. In that case you don’t have to define a parameter name, and can just provide the parameter type. @@ -22,29 +16,45 @@ In that case you don’t have to define a parameter name, and can just provide t For example, this `maximum` method takes a _context parameter_ of type `Ord`, only to pass it on as an argument to `max`: +{% tabs context-bounds-max-named-param class=tabs-scala-version %} + +{% tab 'Scala 2' %} ```scala -def maximum[A](xs: List[A])(using ord: Ord[A]): A = +def maximum[A](xs: List[A])(implicit ord: Ord[A]): A = xs.reduceLeft(max(ord)) ``` +{% endtab %} -In that code the parameter name `ord` isn’t actually required; it can be passed on as an inferred argument to `max`, so you just state that `maximum` uses the type `Ord[A]` without giving it a name: - +{% tab 'Scala 3' %} ```scala -def maximum[A](xs: List[A])(using Ord[A]): A = - xs.reduceLeft(max) +def maximum[A](xs: List[A])(using ord: Ord[A]): A = + xs.reduceLeft(max(using ord)) ``` +{% endtab %} +{% endtabs %} ## Context bounds -Given that background, a _context bound_ is a shorthand syntax for expressing the pattern of, “a context parameter that depends on a type parameter.” +Given that background, a _context bound_ is a shorthand syntax for expressing the pattern of, “a context parameter applied to a type parameter.” Using a context bound, the `maximum` method can be written like this: +{% tabs context-bounds-max-rewritten %} + +{% tab 'Scala 2 and 3' %} + ```scala -def maximum[A: Ord](xs: List[A]): A = xs.reduceLeft(max) +def maximum[A: Ord](xs: List[A]): A = + xs.reduceLeft(max) ``` -A bound like `: Ord` on a type parameter `A` of a method or class indicates a context parameter with `Ord[A]`. +{% endtab %} + +{% endtabs %} + + +A bound like `: Ord` on a type parameter `A` of a method or class indicates a context parameter with type `Ord[A]`. +Under the hood, the compiler transforms this syntax into the one shown in the Background section. -For more information about context bounds, see the [“What are context bounds?”](https://docs.scala-lang.org/tutorials/FAQ/context-bounds.html) section of the Scala FAQ. +For more information about context bounds, see the [“What are context bounds?”]({% link _overviews/FAQ/index.md %}#what-are-context-bounds) section of the Scala FAQ. diff --git a/_overviews/scala3-book/ca-given-imports.md b/_overviews/scala3-book/ca-given-imports.md index 9b009001a9..b60e21f75d 100644 --- a/_overviews/scala3-book/ca-given-imports.md +++ b/_overviews/scala3-book/ca-given-imports.md @@ -7,11 +7,16 @@ num: 62 previous-page: ca-context-bounds next-page: ca-type-classes --- +Scala 3 only To make it more clear where givens in the current scope are coming from, a special form of the `import` statement is used to import `given` instances. The basic form is shown in this example: +{% tabs given-imports-basic-form %} + +{% tab 'Scala 3 Only' %} + ```scala object A: class TC @@ -23,15 +28,27 @@ object B: import A.given // import the given instance ``` +{% endtab %} + +{% endtabs %} + In this code the `import A.*` clause of object `B` imports all members of `A` *except* the `given` instance, `tc`. Conversely, the second import, `import A.given`, imports *only* that `given` instance. The two `import` clauses can also be merged into one: +{% tabs given-imports-merged %} + +{% tab 'Scala 3 Only' %} + ```scala object B: import A.{given, *} ``` +{% endtab %} + +{% endtabs %} + ## Discussion diff --git a/_overviews/scala3-book/ca-given-using-clauses.md b/_overviews/scala3-book/ca-given-using-clauses.md index d762e8719a..a0c747c450 100644 --- a/_overviews/scala3-book/ca-given-using-clauses.md +++ b/_overviews/scala3-book/ca-given-using-clauses.md @@ -63,7 +63,7 @@ def renderWidget(items: List[String])(using c: Config): String = ??? {% endtab %} {% endtabs %} -By starting a parameter section with the keyword `using`, we tell the Scala compiler that at the callsite it should automatically find an argument with the correct type. +By starting a parameter section with the keyword `using`, we tell the Scala compiler that at the call-site it should automatically find an argument with the correct type. The Scala compiler thus performs **term inference**. In our call to `renderWidget(List("cart"))` the Scala compiler will see that there is a term of type `Config` in scope (the `c`) and automatically provide it to `renderWidget`. diff --git a/_overviews/scala3-book/ca-multiversal-equality.md b/_overviews/scala3-book/ca-multiversal-equality.md index dc16effb35..54aed55fa4 100644 --- a/_overviews/scala3-book/ca-multiversal-equality.md +++ b/_overviews/scala3-book/ca-multiversal-equality.md @@ -7,7 +7,11 @@ num: 64 previous-page: ca-type-classes next-page: ca-implicit-conversions --- +New In Scala 3 +> Multiversal Equality is a new language feature that was introduced in Scala 3. +> Because it has no equivalent in Scala 2, all code examples +> in this lesson assume you are using Scala 3. Previously, Scala had *universal equality*: Two values of any types could be compared with each other using `==` and `!=`. This came from the fact that `==` and `!=` are implemented in terms of Java’s `equals` method, which can also compare values of any two reference types.