From 3a4c6f9e3281bf92f706106e2c66ee083422b1ec Mon Sep 17 00:00:00 2001 From: Ben Luo Date: Sat, 19 Nov 2022 22:38:36 +0800 Subject: [PATCH 1/4] add code tabs to num30 --- _overviews/scala3-book/fun-eta-expansion.md | 42 ++++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/_overviews/scala3-book/fun-eta-expansion.md b/_overviews/scala3-book/fun-eta-expansion.md index e9590a65f0..2e7a5eac4a 100644 --- a/_overviews/scala3-book/fun-eta-expansion.md +++ b/_overviews/scala3-book/fun-eta-expansion.md @@ -11,26 +11,36 @@ next-page: fun-hofs When you look at the Scaladoc for the `map` method on Scala collections classes, you see that it’s defined to accept a _function_: +{% tabs for=fun1 %} +{% tab 'Scala 2 and 3' for=fun1 %} + ```scala def map[B](f: (A) => B): List[B] ----------- ``` +{% endtab %} +{% endtabs %} + Indeed, the Scaladoc clearly states, “`f` is the _function_ to apply to each element.” But despite that, somehow you can pass a _method_ into `map`, and it still works: +{% tabs for=fun2 %} +{% tab 'Scala 2 and 3' for=fun2 %} + ```scala def times10(i: Int) = i * 10 // a method List(1, 2, 3).map(times10) // List(10,20,30) ``` +{% endtab %} +{% endtabs %} + Have you ever wondered how this works---how you can pass a _method_ into `map`, which expects a _function_? The technology behind this is known as _Eta Expansion_. It converts an expression of _method type_ to an equivalent expression of _function type_, and it does so seamlessly and quietly. - - ## The differences between methods and functions {% comment %} @@ -45,18 +55,31 @@ Unlike methods, _functions_ are complete objects themselves, making them first-c Their syntax is also different. This example shows how to define a method and a function that perform the same task, determining if the given integer is even: +{% tabs for=fun3 %} +{% tab 'Scala 2 and 3' for=fun3 %} + ```scala def isEvenMethod(i: Int) = i % 2 == 0 // a method val isEvenFunction = (i: Int) => i % 2 == 0 // a function ``` +{% endtab %} +{% endtabs %} + The function truly is an object, so you can use it just like any other variable, such as putting it in a list: +{% tabs for=fun4 %} +{% tab 'Scala 2 and 3' for=fun4 %} + ```scala val functions = List(isEvenFunction) ``` -Conversely, a method technically isn’t an object, so in Scala 2 you couldn’t put a method in a `List`, at least not directly, as shown in this example: +{% endtab %} +{% endtabs %} + +{% tabs for=fun5 class=tabs-scala-version %} +{% tab 'Scala 2' for=fun5 %} ```scala // this example shows the Scala 2 error message @@ -67,13 +90,22 @@ Unapplied methods are only converted to functions when a function type is expect You can make this conversion explicit by writing `isEvenMethod _` or `isEvenMethod(_)` instead of `isEvenMethod`. ``` -As shown in that error message, there is a manual way to convert a method into a function in Scala 2, but the important part for Scala 3 is that the Eta Expansion technology is improved, so now when you attempt to use a method as a variable, it just works---you don’t have to handle the manual conversion yourself: +Conversely, a method technically isn’t an object, so in Scala 2 you couldn’t put a method in a `List`, at least not directly, as shown in this example: + +{% endtab %} + +{% tab 'Scala 3' for=fun5 %} ```scala val functions = List(isEvenFunction) // works val methods = List(isEvenMethod) // works ``` +As shown in that error message, there is a manual way to convert a method into a function in Scala 2, but the important part for Scala 3 is that the Eta Expansion technology is improved, so now when you attempt to use a method as a variable, it just works---you don’t have to handle the manual conversion yourself: + +{% endtab %} +{% endtabs %} + For the purpose of this introductory book, the important things to know are: - Eta Expansion is the Scala technology that lets you use methods just like functions @@ -81,8 +113,6 @@ For the purpose of this introductory book, the important things to know are: For more details on how this works, see the [Eta Expansion page][eta_expansion] in the Reference documentation. - - [eta_expansion]: {{ site.scala3ref }}/changed-features/eta-expansion.html [extension]: {% link _overviews/scala3-book/ca-extension-methods.md %} [toplevel]: {% link _overviews/scala3-book/taste-toplevel-definitions.md %} From 0a202f2feb5663e32a8cb9aaf4b3b5b9613b5952 Mon Sep 17 00:00:00 2001 From: Ben Luo Date: Sun, 20 Nov 2022 15:12:01 +0800 Subject: [PATCH 2/4] correct for errors. --- _overviews/scala3-book/fun-eta-expansion.md | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/_overviews/scala3-book/fun-eta-expansion.md b/_overviews/scala3-book/fun-eta-expansion.md index 2e7a5eac4a..8b74bb09c0 100644 --- a/_overviews/scala3-book/fun-eta-expansion.md +++ b/_overviews/scala3-book/fun-eta-expansion.md @@ -11,8 +11,8 @@ next-page: fun-hofs When you look at the Scaladoc for the `map` method on Scala collections classes, you see that it’s defined to accept a _function_: -{% tabs for=fun1 %} -{% tab 'Scala 2 and 3' for=fun1 %} +{% tabs for=fun_1 %} +{% tab 'Scala 2 and 3' for=fun_1 %} ```scala def map[B](f: (A) => B): List[B] @@ -25,8 +25,8 @@ def map[B](f: (A) => B): List[B] Indeed, the Scaladoc clearly states, “`f` is the _function_ to apply to each element.” But despite that, somehow you can pass a _method_ into `map`, and it still works: -{% tabs for=fun2 %} -{% tab 'Scala 2 and 3' for=fun2 %} +{% tabs for=fun_2 %} +{% tab 'Scala 2 and 3' for=fun_2 %} ```scala def times10(i: Int) = i * 10 // a method @@ -55,8 +55,8 @@ Unlike methods, _functions_ are complete objects themselves, making them first-c Their syntax is also different. This example shows how to define a method and a function that perform the same task, determining if the given integer is even: -{% tabs for=fun3 %} -{% tab 'Scala 2 and 3' for=fun3 %} +{% tabs for=fun_3 %} +{% tab 'Scala 2 and 3' for=fun_3 %} ```scala def isEvenMethod(i: Int) = i % 2 == 0 // a method @@ -68,8 +68,8 @@ val isEvenFunction = (i: Int) => i % 2 == 0 // a function The function truly is an object, so you can use it just like any other variable, such as putting it in a list: -{% tabs for=fun4 %} -{% tab 'Scala 2 and 3' for=fun4 %} +{% tabs for=fun_4 %} +{% tab 'Scala 2 and 3' for=fun_4 %} ```scala val functions = List(isEvenFunction) @@ -78,8 +78,8 @@ val functions = List(isEvenFunction) {% endtab %} {% endtabs %} -{% tabs for=fun5 class=tabs-scala-version %} -{% tab 'Scala 2' for=fun5 %} +{% tabs for=fun_5 class=tabs-scala-version %} +{% tab 'Scala 2' for=fun_5 %} ```scala // this example shows the Scala 2 error message @@ -94,7 +94,7 @@ Conversely, a method technically isn’t an object, so in Scala 2 you couldn’t {% endtab %} -{% tab 'Scala 3' for=fun5 %} +{% tab 'Scala 3' for=fun_5 %} ```scala val functions = List(isEvenFunction) // works From 01eff5346f061b0e488c3d03da7e64f964015856 Mon Sep 17 00:00:00 2001 From: Ben Luo Date: Sun, 20 Nov 2022 16:16:30 +0800 Subject: [PATCH 3/4] finally corrected mistakes. --- _overviews/scala3-book/fun-eta-expansion.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_overviews/scala3-book/fun-eta-expansion.md b/_overviews/scala3-book/fun-eta-expansion.md index 8b74bb09c0..a7e6599346 100644 --- a/_overviews/scala3-book/fun-eta-expansion.md +++ b/_overviews/scala3-book/fun-eta-expansion.md @@ -11,7 +11,7 @@ next-page: fun-hofs When you look at the Scaladoc for the `map` method on Scala collections classes, you see that it’s defined to accept a _function_: -{% tabs for=fun_1 %} +{% tabs fun_1 %} {% tab 'Scala 2 and 3' for=fun_1 %} ```scala @@ -25,7 +25,7 @@ def map[B](f: (A) => B): List[B] Indeed, the Scaladoc clearly states, “`f` is the _function_ to apply to each element.” But despite that, somehow you can pass a _method_ into `map`, and it still works: -{% tabs for=fun_2 %} +{% tabs fun_2 %} {% tab 'Scala 2 and 3' for=fun_2 %} ```scala @@ -55,7 +55,7 @@ Unlike methods, _functions_ are complete objects themselves, making them first-c Their syntax is also different. This example shows how to define a method and a function that perform the same task, determining if the given integer is even: -{% tabs for=fun_3 %} +{% tabs fun_3 %} {% tab 'Scala 2 and 3' for=fun_3 %} ```scala @@ -68,7 +68,7 @@ val isEvenFunction = (i: Int) => i % 2 == 0 // a function The function truly is an object, so you can use it just like any other variable, such as putting it in a list: -{% tabs for=fun_4 %} +{% tabs fun_4 %} {% tab 'Scala 2 and 3' for=fun_4 %} ```scala @@ -78,7 +78,7 @@ val functions = List(isEvenFunction) {% endtab %} {% endtabs %} -{% tabs for=fun_5 class=tabs-scala-version %} +{% tabs fun_5 class=tabs-scala-version %} {% tab 'Scala 2' for=fun_5 %} ```scala From 4bf4ac601cdfde14f3f0061b8b9419ddb847c976 Mon Sep 17 00:00:00 2001 From: Ben Luo Date: Sat, 7 Jan 2023 20:07:49 +0800 Subject: [PATCH 4/4] correct sentence according to review. --- _overviews/scala3-book/fun-eta-expansion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/fun-eta-expansion.md b/_overviews/scala3-book/fun-eta-expansion.md index 393ca08c72..dcfc76acf5 100644 --- a/_overviews/scala3-book/fun-eta-expansion.md +++ b/_overviews/scala3-book/fun-eta-expansion.md @@ -101,7 +101,7 @@ val functions = List(isEvenFunction) // works val methods = List(isEvenMethod) // works ``` -As shown in that error message, there is a manual way to convert a method into a function in Scala 2, but the important part for Scala 3 is that the Eta Expansion technology is improved, so now when you attempt to use a method as a variable, it just works---you don’t have to handle the manual conversion yourself: +The important part for Scala 3 is that the Eta Expansion technology is improved, so now when you attempt to use a method as a variable, it just works---you don’t have to handle the manual conversion yourself. {% endtab %} {% endtabs %}