From 1fdea9f715a01f622b62d82496f7978328e6fb5a Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 10 Oct 2022 17:10:36 +0200 Subject: [PATCH 1/2] update tour/implicit-conversions for Scala 3 --- _tour/implicit-conversions.md | 59 ++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/_tour/implicit-conversions.md b/_tour/implicit-conversions.md index 4915f51daf..78fdb9601f 100644 --- a/_tour/implicit-conversions.md +++ b/_tour/implicit-conversions.md @@ -10,46 +10,33 @@ previous-page: implicit-parameters redirect_from: "/tutorials/tour/implicit-conversions.html" --- -An implicit conversion from type `S` to type `T` is defined by an implicit value which has function type `S => T`, or by an implicit method convertible to a value of that type. +{% tabs implicit-conversion-defn class=tabs-scala-version %} +{% tab 'Scala 2' %} +In Scala 2, an implicit conversion from type `S` to type `T` is defined by an [implicit value]({% link _tour/implicit-parameters.md %}) which has function type `S => T`, or by an implicit method convertible to a value of that type. +{% endtab %} +{% tab 'Scala 3' %} +In Scala 3, an implicit conversion from type `S` to type `T` is defined by a [given instance]({% link _tour/implicit-parameters.md %}) which has type `scala.Conversion[S, T]`, or by an implicit method which can be eta-expanded to the function type `S => T`. +{% endtab %} +{% endtabs %} Implicit conversions are applied in two situations: -* If an expression `e` is of type `S`, and `S` does not conform to the expression's expected type `T`. -* In a selection `e.m` with `e` of type `S`, if the selector `m` does not denote a member of `S`. +1. If an expression `e` is of type `S`, and `S` does not conform to the expression's expected type `T`. +2. In a selection `e.m` with `e` of type `S`, if the selector `m` does not denote a member of `S`. In the first case, a conversion `c` is searched for which is applicable to `e` and whose result type conforms to `T`. -In the second case, a conversion `c` is searched for which is applicable to `e` and whose result contains a member named `m`. - -If an implicit method `List[A] => Ordered[List[A]]` is in scope, as well as an implicit method `Int => Ordered[Int]`, the following operation on the two lists of type `List[Int]` is legal: - -``` -List(1, 2, 3) <= List(4, 5) -``` - -An implicit method `Int => Ordered[Int]` is provided automatically through `scala.Predef.intWrapper`. An example of an implicit method `List[A] => Ordered[List[A]]` is provided below. - -```scala mdoc -import scala.language.implicitConversions -implicit def list2ordered[A](x: List[A]) - (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = - new Ordered[List[A]] { - //replace with a more useful implementation - def compare(that: List[A]): Int = 1 - } -``` +An example is to pass a `scala.Int`, e.g. `x`, to a method that expects `scala.Long`. In this case, the implicit conversion `Int.int2long(x)` is inserted. -The implicitly imported object `scala.Predef` declares several aliases to frequently used types (e.g. `scala.collection.immutable.Map` is aliased to `Map`) and methods (e.g. `assert`) but also several implicit conversions. -For example, when calling a Java method that expects a `java.lang.Integer`, you are free to pass it a `scala.Int` instead. That's because Predef includes the following implicit conversions: +In the second case, a conversion `c` is searched for which is applicable to `e` and whose result contains a member named `m`. -```scala mdoc -import scala.language.implicitConversions +An example is to compare two strings `"foo" < "bar"`. In this case, `String` has no member `<`, so the implicit conversion `Predef.augmentString("foo") < "bar"` is inserted. -implicit def int2Integer(x: Int) = - java.lang.Integer.valueOf(x) -``` +**Beware the power of implicit conversions:** +{% tabs implicit-conversion-warning class=tabs-scala-version %} +{% tab 'Scala 2' %} Because implicit conversions can have pitfalls if used indiscriminately the compiler warns when compiling the implicit conversion definition. To turn off the warnings take either of these actions: @@ -58,3 +45,17 @@ To turn off the warnings take either of these actions: * Invoke the compiler with `-language:implicitConversions` No warning is emitted when the conversion is applied by the compiler. +{% endtab %} +{% tab 'Scala 3' %} +Because implicit conversions can have pitfalls if used indiscriminately the compiler warns in two situations: +- when compiling the implicit conversion definition (for Scala 2 style conversions). +- at the call site where a given instance of `scala.Conversion` is inserted as a conversion. + +To turn off the warnings take either of these actions: + +- Import `scala.language.implicitConversions` into the scope of: + - the implicit conversion definition (for Scala 2 style conversions) + - the call site (when an inserted conversion was defined by a given instance of `scala.Conversion`) +- Invoke the compiler with `-language:implicitConversions` +{% endtab %} +{% endtabs %} From b679db219bc7583f8097fd82691429f9594ebdaa Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Wed, 9 Nov 2022 11:05:26 +0100 Subject: [PATCH 2/2] address comments --- _tour/implicit-conversions.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/_tour/implicit-conversions.md b/_tour/implicit-conversions.md index 78fdb9601f..80e1a64196 100644 --- a/_tour/implicit-conversions.md +++ b/_tour/implicit-conversions.md @@ -15,7 +15,7 @@ redirect_from: "/tutorials/tour/implicit-conversions.html" In Scala 2, an implicit conversion from type `S` to type `T` is defined by an [implicit value]({% link _tour/implicit-parameters.md %}) which has function type `S => T`, or by an implicit method convertible to a value of that type. {% endtab %} {% tab 'Scala 3' %} -In Scala 3, an implicit conversion from type `S` to type `T` is defined by a [given instance]({% link _tour/implicit-parameters.md %}) which has type `scala.Conversion[S, T]`, or by an implicit method which can be eta-expanded to the function type `S => T`. +In Scala 3, an implicit conversion from type `S` to type `T` is defined by a [given instance]({% link _tour/implicit-parameters.md %}) which has type `scala.Conversion[S, T]`. For compatibility with Scala 2, they can also be defined by an implicit method (read more in the Scala 2 tab). {% endtab %} {% endtabs %} @@ -24,14 +24,14 @@ Implicit conversions are applied in two situations: 1. If an expression `e` is of type `S`, and `S` does not conform to the expression's expected type `T`. 2. In a selection `e.m` with `e` of type `S`, if the selector `m` does not denote a member of `S`. -In the first case, a conversion `c` is searched for which is applicable to `e` and whose result type conforms to `T`. +In the first case, a conversion `c` is searched for, which is applicable to `e` and whose result type conforms to `T`. An example is to pass a `scala.Int`, e.g. `x`, to a method that expects `scala.Long`. In this case, the implicit conversion `Int.int2long(x)` is inserted. -In the second case, a conversion `c` is searched for which is applicable to `e` and whose result contains a member named `m`. +In the second case, a conversion `c` is searched for, which is applicable to `e` and whose result contains a member named `m`. -An example is to compare two strings `"foo" < "bar"`. In this case, `String` has no member `<`, so the implicit conversion `Predef.augmentString("foo") < "bar"` is inserted. +An example is to compare two strings `"foo" < "bar"`. In this case, `String` has no member `<`, so the implicit conversion `Predef.augmentString("foo") < "bar"` is inserted. (`scala.Predef` is automatically imported into all Scala programs.) **Beware the power of implicit conversions:** @@ -48,14 +48,14 @@ No warning is emitted when the conversion is applied by the compiler. {% endtab %} {% tab 'Scala 3' %} Because implicit conversions can have pitfalls if used indiscriminately the compiler warns in two situations: -- when compiling the implicit conversion definition (for Scala 2 style conversions). +- when compiling a Scala 2 style implicit conversion definition. - at the call site where a given instance of `scala.Conversion` is inserted as a conversion. To turn off the warnings take either of these actions: - Import `scala.language.implicitConversions` into the scope of: - - the implicit conversion definition (for Scala 2 style conversions) - - the call site (when an inserted conversion was defined by a given instance of `scala.Conversion`) + - a Scala 2 style implicit conversion definition + - call sites where a given instance of `scala.Conversion` is inserted as a conversion. - Invoke the compiler with `-language:implicitConversions` {% endtab %} {% endtabs %}