Skip to content

Commit 33540f3

Browse files
adpi2b-studios
authored andcommitted
Review Taste of Scala
1 parent 06123db commit 33540f3

8 files changed

+57
-29
lines changed

_overviews/scala3-book/taste-collections.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ next-page: taste-contextual-abstractions
99

1010

1111

12-
Scala has a rich set of collections classes, and those classes have a rich set of methods.
12+
The Scala library has a rich set of collection classes, and those classes have a rich set of methods.
1313
Collections classes are available in both immutable and mutable forms.
1414

1515

@@ -98,7 +98,7 @@ t._2 // "eleven"
9898
t._3 // Person("Eleven")
9999
```
100100

101-
You can also use this *extractor* approach to assign the tuple fields to variable names:
101+
You can also use this _extractor_ approach to assign the tuple fields to variable names:
102102

103103
```scala
104104
val (num, str, person) = t

_overviews/scala3-book/taste-contextual-abstractions.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,43 @@ next-page: taste-toplevel-definitions
1212
TODO: Now that this is a separate section, it needs a little more content.
1313
{% endcomment %}
1414

15+
Under certain circumstances, you can omit some parameters of method calls that are considered repetitive.
1516

16-
Under certain circumstances, the Scala compiler can “write” some parts of your programs.
17-
For instance, consider a program that sorts a list of addresses by two criteria, city name and then street name:
17+
Those parameters are called _Context Parameters_ because they are inferred by the compiler from the context surrounding the method call.
18+
19+
For instance, consider a program that sorts a list of addresses by two criteria: the city name and then street name.
1820

1921
```scala
2022
val addresses: List[Address] = ...
23+
2124
addresses.sortBy(address => (address.city, address.street))
2225
```
2326

24-
The sorting algorithm needs to compare addresses by first comparing their city names, and then also their street names when the city names are the same.
25-
However, with the use of contextual abstraction, you don’t need to manually define this ordering relation, because the compiler is able to summon it automatically based on an existing ordering relation for comparing string values.
27+
The `sortBy` method takes a function that returns, for every address, the value to compare it with the other addresses.
28+
In this case, we pass a function that returns a pair containing the city name and the street name.
29+
30+
Note that we only indicate _what_ to compare, but not _how_ to perform the comparison.
31+
How does the sorting algorithm know how to compare pairs of `String`?
32+
33+
Actually, the `sortBy` method takes a second parameter---a context parameter---that is inferred by the compiler.
34+
It does not appear in the above example because it is supplied by the compiler.
35+
36+
This second parameter implements the _how_ to compare.
37+
It is convenient to omit it because we know `String`s are generally compared using the lexicographic order.
38+
39+
However, it is also possible to pass it explicitly:
40+
41+
```scala
42+
addresses.sortBy(address => (address.city, address.street))(using Ordering.Tuple2(Ordering.String, Ordering.String))
43+
```
44+
45+
In this case, the `Ordering.Tuple2(Ordering.String, Ordering.String)` instance is exactly the one that is otherwise inferred by the compiler.
46+
In other words both examples produce the same program.
47+
48+
_Contextual Abstractions_ is used to avoid repetition of code.
49+
It helps developers write pieces of code that are extensible and concise at the same time.
2650

27-
For more details, see the [Contextual Abstractions chapter][contextual] of this book, and also in the [Reference documentation][reference].
51+
For more details, see the [Contextual Abstractions chapter][contextual] of this book, and also the [Reference documentation][reference].
2852

2953

3054

_overviews/scala3-book/taste-control-structures.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ yield
136136
// of code here
137137
f.length
138138

139-
// result: List[Int] = List(5, 6, 6)
139+
// fruitLengths: List[Int] = List(5, 6, 6)
140140
```
141141

142142
`for` loops and expressions are covered in more detail in the [Control Structures sections][control] of this book, and in the [Reference documentation]({{ site.scala3ref }}/other-new-features/control-syntax.html).

_overviews/scala3-book/taste-functions.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@ Scala has most features you’d expect in a functional programming language, inc
1313

1414
- Lambdas
1515
- Higher-order functions (HOFs)
16-
- Higher-order functions in the standard library
16+
- Immutable collections in the standard library
1717

1818
Lambdas, also known as _anonymous functions_, are a big part of keeping your code concise but readable.
19-
These two examples---which show how to call higher-order functions (HOFs) on a Scala `List`---are equivalent, and show how to multiply each number in a list by `2` by passing a lambda into the `map` method:
19+
20+
The `map` method of the `List` class is a typical example of a higher-order function---a function that takes a lambda as parameter.
21+
22+
These two examples are equivalent, and show how to multiply each number in a list by `2` by passing a lambda into the `map` method:
2023

2124
```scala
2225
val a = List(1, 2, 3).map(i => i * 2) // List(2,4,6)
2326
val b = List(1, 2, 3).map(_ * 2) // List(2,4,6)
2427
```
2528

26-
Those examples are also equivalent to the following code, which uses a `double` method inside of `map` instead of a lambda:
29+
Those examples are also equivalent to the following code, which uses a `double` method instead of a lambda:
2730

2831
```scala
2932
def double(i: Int): Int = i * 2

_overviews/scala3-book/taste-methods.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ next-page: taste-functions
1111
## Scala methods
1212

1313
Scala classes, case classes, traits, enums, and objects can all contain methods.
14-
When a method isn’t declared to use a generic type or accept `using` parameters, its general syntax looks like this:
14+
The syntax of a simple method looks like this:
1515

1616
```scala
1717
def methodName(param1: Type1, param2: Type2): ReturnType =
1818
// the method body
1919
// goes here
2020
```
2121

22-
Here are a few examples of that syntax:
22+
Here are a few examples:
2323

2424
```scala
2525
def sum(a: Int, b: Int): Int = a + b
@@ -50,7 +50,7 @@ def getStackTraceAsString(t: Throwable): String =
5050
```
5151

5252
Method parameters can also have default values.
53-
In this example, if the `timeout` parameter isn’t specified, it defaults to `5000`:
53+
In this example, the `timeout` parameter has a default value of `5000`:
5454

5555
```scala
5656
def makeConnection(url: String, timeout: Int = 5000): Unit =
@@ -100,15 +100,15 @@ For instance, if you want to add two methods named `hello` and `aloha` to the `S
100100

101101
```scala
102102
extension (s: String)
103-
def hello: String = s"Hello, ${s.capitalize}"
104-
def aloha: String = s"Aloha, ${s.capitalize}"
103+
def hello: String = s"Hello, ${s.capitalize}!"
104+
def aloha: String = s"Aloha, ${s.capitalize}!"
105105

106-
"world".hello // "Hello, World"
107-
"friend".aloha // "Aloha, Friend"
106+
"world".hello // "Hello, World!"
107+
"friend".aloha // "Aloha, Friend!"
108108
```
109109

110-
The `extension` keyword declares that you’re about to define one or more extension methods on the type that’s put in parentheses.
111-
As shown with this `String` example, the parameter `s` can then be used in the body of your extension methods.
110+
The `extension` keyword declares that you’re about to define one or more extension methods on the parameter that’s put in parentheses.
111+
As shown with this example, the parameter `s` of type `String` can then be used in the body of your extension methods.
112112

113113
This next example shows how to add a `makeInt` method to the `String` class.
114114
Here, `makeInt` takes a parameter named `radix`.
@@ -127,7 +127,8 @@ extension (s: String)
127127

128128
## See also
129129

130-
Methods are covered in detail in the [Data Modeling][data-1] section.
130+
Scala Methods can be much more powerful: they can take type parameters and context parameters.
131+
They are covered in detail in the [Data Modeling][data-1] section.
131132

132133

133134

_overviews/scala3-book/taste-modeling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ These examples show how those classes are used:
7676

7777
```scala
7878
val d = Dog("Rover")
79-
d.speak() // prints "Woof!"
79+
println(d.speak()) // prints "Woof!"
8080

8181
val c = Cat("Morris")
82-
c.speak() // "Meow"
82+
println(c.speak()) // "Meow"
8383
c.startRunning() // "Yeah ... I don’t run"
8484
c.stopRunning() // "No need to stop"
8585
```

_overviews/scala3-book/taste-objects.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ println(multiply(2,2)) // 4
8888
{% comment %}
8989
NOTE: I don’t know if this is worth keeping, but I’m leaving it here as a comment for now.
9090

91-
> You may read that objects are used to *reify* traits into modules.
92-
> *Reify* means, “to take an abstract concept and turn it into something concrete.” This is what happens in these examples, but “implement” is a more familiar word for most people than “reify.”
91+
> You may read that objects are used to _reify_ traits into modules.
92+
> _Reify_ means, “to take an abstract concept and turn it into something concrete.” This is what happens in these examples, but “implement” is a more familiar word for most people than “reify.”
9393
{% endcomment %}
9494

9595

_overviews/scala3-book/taste-toplevel-definitions.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ next-page: taste-summary
99

1010

1111
In Scala 3, all kinds of definitions can be written at the “top level” of your source code files.
12-
For instance, you can create a file named *MyCoolApp.scala* and put these contents into it:
12+
For instance, you can create a file named _MyCoolApp.scala_ and put these contents into it:
1313

1414
```scala
1515
import scala.collection.mutable.ArrayBuffer
@@ -42,8 +42,8 @@ As shown, there’s no need to put those definitions inside a `package`, `class`
4242

4343
## Replaces package objects
4444

45-
If you’re familiar with Scala 2, this approach replaces *package objects*.
46-
But while being much easier to use, they work similarly: When you place a definition in a package named *foo*, you can then access that definition under all other packages under *foo*, such as within the *foo.bar* package in this example:
45+
If you’re familiar with Scala 2, this approach replaces _package objects_.
46+
But while being much easier to use, they work similarly: When you place a definition in a package named _foo_, you can then access that definition under all other packages under _foo_, such as within the _foo.bar_ package in this example:
4747

4848
```scala
4949
package foo {
@@ -60,6 +60,6 @@ package foo {
6060

6161
Curly braces are used in this example to put an emphasis on the package nesting.
6262

63-
The benefit of this approach is that you can place definitions under a package named *com.acme.myapp*, and then those definitions can be referenced within *com.acme.myapp.model*, *com.acme.myapp.controller*, etc.
63+
The benefit of this approach is that you can place definitions under a package named _com.acme.myapp_, and then those definitions can be referenced within _com.acme.myapp.model_, _com.acme.myapp.controller_, etc.
6464

6565

0 commit comments

Comments
 (0)