Skip to content

Commit df9483d

Browse files
committed
Suggestions on the Scala 3 book (part 5)
1 parent baff05d commit df9483d

File tree

6 files changed

+109
-76
lines changed

6 files changed

+109
-76
lines changed

_overviews/scala3-book/concurrency.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ You’ll also see examples of methods that are used to handle the value in a fut
5555

5656
> When you think about futures, it’s important to know that they’re intended as a one-shot, “Handle this relatively slow computation on some other thread, and call me back with a result when you’re done” construct.
5757
> As a point of contrast, [Akka](https://akka.io) actors are intended to run for a long time and respond to many requests during their lifetime.
58-
> While an actor may live forever, a future is intended to be run only once.
58+
> While an actor may live forever, a future eventually contains the result
59+
> of a computation that ran only once.
5960
6061

6162

@@ -77,7 +78,7 @@ Now you’re ready to create a future.
7778
For this example, first define a long-running, single-threaded algorithm:
7879

7980
```scala
80-
def longRunningAlgorithm =
81+
def longRunningAlgorithm() =
8182
Thread.sleep(10_000)
8283
42
8384
```
@@ -86,29 +87,29 @@ That fancy algorithm returns the integer value `42` after a ten second delay.
8687
Now call that algorithm by wrapping it into the `Future` constructor, and assigning the result to a variable:
8788

8889
```scala
89-
scala> val f = Future(longRunningAlgorithm)
90-
f: scala.concurrent.Future[Int] = Future(<not completed>)
90+
scala> val eventualInt = Future(longRunningAlgorithm())
91+
eventualInt: scala.concurrent.Future[Int] = Future(<not completed>)
9192
```
9293

93-
Right away your future begins running.
94-
If you immediately check the value of the variable `f`, you see that the future hasn’t completed yet:
94+
Right away, your computation---the call to `longRunningAlgorithm()`---begins running.
95+
If you immediately check the value of the variable `eventualInt`, you see that the future hasn’t been completed yet:
9596

9697
```scala
97-
scala> f
98+
scala> eventualInt
9899
val res1: scala.concurrent.Future[Int] = Future(<not completed>)
99100
```
100101

101-
But if you check again after ten seconds, you’ll see that it completes successfully:
102+
But if you check again after ten seconds, you’ll see that it is completed successfully:
102103

103104
```scala
104-
scala> f
105+
scala> eventualInt
105106
val res2: scala.concurrent.Future[Int] = Future(Success(42))
106107
```
107108

108109
While that’s a relatively simple example, it shows the basic approach: Just construct a new `Future` with your long-running algorithm.
109110

110111
One thing to notice is that the `42` you expected is wrapped in a `Success`, which is further wrapped in a `Future`.
111-
This is a key concept to understand: the value in a `Future` is always an instance of one of the *scala.util.Try* types: `Success` or `Failure`.
112+
This is a key concept to understand: the value in a `Future` is always an instance of one of the `scala.util.Try` types: `Success` or `Failure`.
112113
Therefore, when you work with the result of a future, you use the usual `Try`-handling techniques.
113114

114115

@@ -118,7 +119,7 @@ Therefore, when you work with the result of a future, you use the usual `Try`-ha
118119
This is what the result looks like when you call `map` right after creating the variable `f`:
119120

120121
```scala
121-
scala> val a = f.map(_ * 2)
122+
scala> val a = eventualInt.map(_ * 2)
122123
a: scala.concurrent.Future[Int] = Future(<not completed>)
123124
```
124125

@@ -139,13 +140,13 @@ In addition to higher-order functions like `map`, you can also use callback meth
139140
One commonly used callback method is `onComplete`, which takes a *partial function* in which you handle the `Success` and `Failure` cases:
140141

141142
```scala
142-
f.onComplete {
143+
eventualInt.onComplete {
143144
case Success(value) => println(s"Got the callback, value = $value")
144145
case Failure(e) => e.printStackTrace
145146
}
146147
```
147148

148-
When you paste that code in the REPL you’ll see the result:
149+
When you paste that code in the REPL you’ll eventually see the result:
149150

150151
```scala
151152
Got the callback, value = 42
@@ -180,7 +181,7 @@ See the [Futures and Promises][futures] page for a discussion of additional meth
180181

181182
## Running multiple futures and joining their results
182183

183-
To run multiple futures in parallel and join their results when all of the futures complete, use a `for` expression.
184+
To run multiple computations in parallel and join their results when all of the futures have been completed, use a `for` expression.
184185
The correct approach is:
185186

186187
1. Create the futures
@@ -198,8 +199,8 @@ import scala.concurrent.Future
198199
import scala.concurrent.ExecutionContext.Implicits.global
199200
import scala.util.{Failure, Success}
200201

201-
val startTime = System.currentTimeMillis
202-
def delta() = System.currentTimeMillis - startTime
202+
val startTime = System.currentTimeMillis()
203+
def delta() = System.currentTimeMillis() - startTime
203204
def sleep(millis: Long) = Thread.sleep(millis)
204205

205206
@main def multipleFutures1 =

_overviews/scala3-book/interacting-with-java.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,8 @@ You can convert that Java list to a Scala `Seq`, using the conversion utilities
5858
```scala
5959
// scala
6060
import scala.jdk.CollectionConverters.*
61-
import java.util.List
6261

63-
def testList =
62+
def testList() =
6463
println("Using a Java List in Scala")
6564
val javaList: java.util.List[String] = JavaClass.getStrings()
6665
val scalaSeq: Seq[String] = javaList.asScala.toSeq
@@ -156,7 +155,7 @@ class Dog extends Animal, Wagging, Running:
156155

157156
## How to use Scala collections in Java
158157

159-
When you need to use a Scala collection class in your Java code, use the methods of Scala’s _scala.jdk.javaapi.CollectionConverters_ object in your Java code to make the conversions work.
158+
When you need to use a Scala collection class in your Java code, use the methods of Scala’s `scala.jdk.javaapi.CollectionConverters` object in your Java code to make the conversions work.
160159
For example, if you have a `List[String]` like this in a Scala class:
161160

162161
```scala
@@ -192,7 +191,7 @@ Here are a few things to notice in that code:
192191

193192
## How to use Scala `Option` in Java
194193

195-
When you need to use a Scala `Option` in your Java code, you can convert the `Option` to a Java `Optional` value using the `toJava` method of the Scala _scala.jdk.javaapi.OptionConverters_ object.
194+
When you need to use a Scala `Option` in your Java code, you can convert the `Option` to a Java `Optional` value using the `toJava` method of the Scala `scala.jdk.javaapi.OptionConverters` object.
196195

197196
To demonstrate this, create a Scala class with two `Option[String]` values, one containing a string and the other one empty:
198197

@@ -203,7 +202,7 @@ object ScalaObject:
203202
val noneString: Option[String] = None
204203
```
205204

206-
Then in your Java code, convert those `Option[String]` values into `java.util.Optional[String]` using the `toJava` method from the _scala.jdk.javaapi.OptionConverters_ object:
205+
Then in your Java code, convert those `Option[String]` values into `java.util.Optional[String]` using the `toJava` method from the `scala.jdk.javaapi.OptionConverters` object:
207206

208207
```java
209208
// java
@@ -258,7 +257,7 @@ System.out.println(jm.multiply(3,4)); // 12
258257
## How to handle Scala methods that throw exceptions in Java code
259258

260259
When you’re writing Scala code using Scala programming idioms, you’ll never write a method that throws an exception.
261-
But if for some reason you have a Scala method that does throw an exception, and you want Java developers to be able to use that method, add the `@throws` annotation to your Scala method so Java consumers will know the exceptions they can throw.
260+
But if for some reason you have a Scala method that does throw an exception, and you want Java developers to be able to use that method, add the `@throws` annotation to your Scala method so Java consumers will know the exceptions it can throw.
262261

263262
For example, this Scala `exceptionThrower` method is annotated to declare that it throws an `Exception`:
264263

_overviews/scala3-book/scala-for-java-devs.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Also at a high level, the differences between Java and Scala are:
4949
- Scala has a full suite of immutable collections, including `List`, `Vector`, and immutable `Map` and `Set` implementations
5050
- Everything in Scala is an _expression_: constructs like `if` statements, `for` loops, `match` expressions, and even `try`/`catch` expressions all have return values
5151
- Scala idioms favor immutability by default: you’re encouraged to use immutable (`final`) variables and immutable collections
52+
- Idiomatic Scala code does not use `null`, and thus does not suffer from `NullPointerException`
5253
- The Scala ecosystem has other [build tools][tools] in sbt, Mill, and others
5354
- In addition to running on the JVM, the [Scala.js](https://www.scala-js.org) project lets you use Scala as a JavaScript replacement
5455
- The [Scala Native](http://www.scala-native.org) project adds low-level constructs to let you write “systems” level code, and also compiles to native executables
@@ -122,9 +123,9 @@ This section provides comparisons of features related to OOP-style classes and m
122123
<tr>
123124
<td class="java-block">
124125
<code>class Person {
125-
<br>&nbsp; private String firstName;
126-
<br>&nbsp; private String lastName;
127-
<br>&nbsp; private int age;
126+
<br>&nbsp; String firstName;
127+
<br>&nbsp; String lastName;
128+
<br>&nbsp; int age;
128129
<br>&nbsp; public Person(
129130
<br>&nbsp;&nbsp;&nbsp; String firstName,
130131
<br>&nbsp;&nbsp;&nbsp; String lastName, int age
@@ -424,7 +425,7 @@ This section compares Java interfaces to Scala traits, including how classes ext
424425
<tbody>
425426
<tr>
426427
<td class="java-block">
427-
<code>class Dog extends Animal, HasLegs, HasTail</code>
428+
<code>class Dog extends Animal implements HasLegs, HasTail</code>
428429
</td>
429430
</tr>
430431
<tr>
@@ -976,7 +977,7 @@ val a = Array("a", "b")
976977
as being backed by this Java `String[]`:
977978

978979
```scala
979-
String[] a = ["a", "b"]
980+
String[] a = ["a", "b"];
980981
```
981982

982983
However, a Scala `Array` also has all of the functional methods you expect in a Scala collection, including `map` and `filter`:
@@ -1275,7 +1276,7 @@ For more information on dealing with errors and exceptions in Scala, see the [Fu
12751276

12761277
That concludes are comparison of the Java and Scala languages.
12771278

1278-
Currently there are other concepts in Scala which currently have no equal in Java 11.
1279+
There are other concepts in Scala which currently have no equal in Java 11.
12791280
This includes:
12801281

12811282
- Everything related to Scala’s [contextual abstractions][contextual]

_overviews/scala3-book/scala-for-javascript-devs.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ At a high level, Scala shares these similarities with JavaScript:
3636
- Both languages have similar `if` statements, `while` loops, and `for` loops
3737
- Starting [at this Scala.js page](https://www.scala-js.org/libraries/index.html), you’ll find dozens of libraries to support React, Angular, jQuery, and many other JavaScript and Scala libraries
3838
- JavaScript objects are mutable; Scala objects _can_ be mutable when writing in an imperative style
39-
- Both JavaScript and Scala support _promises_ as a way of running asynchronous computations ([Scala concurrency][concurrency] uses futures and promises)
39+
- Both JavaScript and Scala support _promises_ as a way of handling the result of asynchronous computations ([Scala concurrency][concurrency] uses futures and promises)
4040

4141
### High-level differences
4242

@@ -441,7 +441,7 @@ In both JavaScript and Scala, functions are objects, so their functionality is s
441441
</tr>
442442
<tr>
443443
<td class="scala-block">
444-
<code>// technically this is a “method,” not a function
444+
<code>// technically this is a “method”, not a function
445445
<br>def add(a: Int, b: Int) = a + b
446446
<br>add(2, 2)&nbsp;&nbsp; // 4</code>
447447
</td>
@@ -474,7 +474,7 @@ In both JavaScript and Scala, functions are objects, so their functionality is s
474474
</table>
475475

476476
In Scala, showing the `Int` return type is optional.
477-
It’s _not_ shown in the `add` example and _is_ shown in the `addThenDouble` example, so you can see both approaches.
477+
It’s _not_ shown in the `add` example and _is_ shown in the `addAndDouble` example, so you can see both approaches.
478478

479479

480480

_overviews/scala3-book/scala-for-python-devs.md

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ These examples demonstrate how to create variables in Python and Scala.
224224
</tbody>
225225
</table>
226226

227-
If a Scala field is going to be mutable, use `var` instead of `val` for variable assignment:
227+
If a Scala field is going to be mutable, use `var` instead of `val` for variable definition:
228228

229229
```scala
230230
var x = 1
@@ -625,18 +625,14 @@ Scala also has `match` expressions.
625625
<tbody>
626626
<tr>
627627
<td class="python-block">
628-
<code>x = [i*10 for i in range(1,4)]
629-
<br># x: [10,20,30]</code>
628+
<code>xs = [i * 10 for i in range(1, 4)]
629+
<br># xs: [10,20,30]</code>
630630
</td>
631631
</tr>
632632
<tr>
633633
<td class="scala-block">
634-
<code>val x =
635-
<br>&nbsp; for
636-
<br>&nbsp;&nbsp;&nbsp; i &lt;- 1 to 3
637-
<br>&nbsp; yield
638-
<br>&nbsp;&nbsp;&nbsp; i * 10
639-
<br>// x: Vector(10, 20, 30)</code>
634+
<code>val xs = for i &lt;- 1 to 3 yield i * 10
635+
<br>// xs: Vector(10, 20, 30)</code>
640636
</td>
641637
</tr>
642638
</tbody>
@@ -888,9 +884,7 @@ However, the default Scala map is _immutable_, and has a number of transformatio
888884
</tr>
889885
<tr>
890886
<td class="scala-block">
891-
<code>for
892-
<br>&nbsp; (key,value) &lt;- myMap
893-
<br>do
887+
<code>for (key,value) &lt;- myMap do
894888
<br>&nbsp; println(key)
895889
<br>&nbsp; println(value)</code>
896890
</td>
@@ -928,7 +922,7 @@ The Python set is similar to the _mutable_ Scala `Set` class.
928922
<tr>
929923
<td class="python-block">
930924
<code>set = {1,2,1}
931-
<br># set: {1,2}</code></td>
925+
<br># set: {1,2}</code>
932926
</td>
933927
</tr>
934928
<tr>
@@ -1006,7 +1000,7 @@ Those lists are used in the following table, that shows how to apply mapping and
10061000
<tbody>
10071001
<tr>
10081002
<td class="python-block">
1009-
<code>x = [i*10 for i in numbers]</code>
1003+
<code>x = [i * 10 for i in numbers]</code>
10101004
</td>
10111005
</tr>
10121006
<tr>
@@ -1028,7 +1022,9 @@ Those lists are used in the following table, that shows how to apply mapping and
10281022
</tr>
10291023
<tr>
10301024
<td class="scala-block">
1031-
<code>val evens = numbers.filter(_ % 2 == 0)</code>
1025+
<code>val evens = numbers.filter(_ % 2 == 0)
1026+
<br>// or
1027+
<br>val evens = for i <- numbers if i % 2 == 0 yield i</code>
10321028
</td>
10331029
</tr>
10341030
</tbody>
@@ -1045,8 +1041,9 @@ Those lists are used in the following table, that shows how to apply mapping and
10451041
</tr>
10461042
<tr>
10471043
<td class="scala-block">
1048-
<code>val x = numbers.filter(_ % 2 == 0)
1049-
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(_ * 10)</code>
1044+
<code>val x = numbers.filter(_ % 2 == 0).map(_ * 10)
1045+
<br>// or
1046+
<br>val x = for i <- numbers if i % 2 == 0 yield i * 10</code>
10501047
</td>
10511048
</tr>
10521049
</tbody>
@@ -1058,8 +1055,7 @@ Those lists are used in the following table, that shows how to apply mapping and
10581055
<tbody>
10591056
<tr>
10601057
<td class="python-block">
1061-
<code>def times_10(n): return n * 10
1062-
<br>x = map(lambda x: x * 10, numbers)</code>
1058+
<code>x = map(lambda x: x * 10, numbers)</code>
10631059
</td>
10641060
</tr>
10651061
<tr>

0 commit comments

Comments
 (0)