Martin Odersky, Lex Spoon, Bill Venners:Scala スケーラブルプログラミング 第 4 版

作成日 : 2023-04-01
最終更新日 :

概要

本書の「はじめに」から引用する。

プログラミングについての一般的な知識は必要である。初めて学ぶプログラミング言語として Scala は決して悪くないが、 本書はプログラミングの書法を学ぶための本ではない。

感想

本書の「はじめに」では次のように書かれている。

途中を飛ばして後の方の章をのぞくと、よくわからない概念を使って説明が進められているという感じがするかもしれない。 しかし、最初から順に章を読んでいけば、 1 ステップずつ積み上げて Scala の能力を高めていくことができるはずだ。

途中を飛ばして本を読む悪い癖のある私は、やはり本書の読者としては不適格なのだろう。

実行

「はじめに」によれば、本書のコード例は Scala ver. 2.13.1 でコンパイルして確認している。とある。 私は、Scala ver. 3.2.2 で本書にある例を試した。 コマンド scala でのソースコードを読み込ませても本書とは異なりエラーが出る。 本書の p.24 の最初のコードブロックは次のとおりである。

println("Hello, world, from a script!")

しかし、これではエラーが出る。

PS C:> scala .\hello.scala
-- [E103] Syntax Error: C:hello.scala:1:0
1 |println("Hello world, from a script!")
  |^^^^^^^
  |Illegal start of toplevel definition
  |
  | longer explanation available when compiling with `-explain`
1 error found
Errors encountered during compilation	

このエラーは、Scala の ver. 3 により起きるものだ。このエラーを防ぐには、次のように @main を用いる。コードは次のとおり。

@main def hello() = println("Hello world, from a script!")

コマンドプロンプトでは次のとおり、正常に結果が表示される。

$ scala hello.scala
Hello, world, from a script!

参考 https://docs.scala-lang.org/scala3/book/methods-main-methods.html

args

また、p.054 の 2.5 節(p.054)の最初のコードブロックでは args という変数が特に定義もなく出ている。これも Ver. 2 だからで、 Ver.3 ではできない。そのため、Ver. 3 では、このコードを次のように書き換え、args を明示する。


@main def main(*args) =
  var i = 0
  while ( i < args.length) {
    println(args(i))
    i += 1
  }

第 06 章 関数型スタイルのオブジェクト

クラス定義を REPL で読み込む

本章をはじめ、この本のあちこちで、クラスの定義がコードブロックで与えられている。そして、 そのクラスが定義されていることが前提となって Scala の REPL (インタプリタモード)で そのクラスを実行した結果がやはりコードブロックで示されている。ところが、 REPL でクラスを読み込ませる方法がわからない。そこで ChatGPT に尋ねてみた。

Q. scala のREPL起動時に最初にファイル(スクリプトファイル等)を実行するにはどうしたらいいですか
A. ScalaのREPLで最初にファイルを実行するには、以下の手順を実行します。

1. ScalaのREPLを起動します。
2. :load コマンドを使用して、実行したいスクリプトファイルのパスを指定します。
例えば、以下のようにコマンドを入力します。
:load /path/to/my/script.scala
3.スクリプトファイルが正しくロードされた場合、REPLでスクリプトの内容が表示されます。
4.スクリプトを実行するには、REPLで定義された関数や変数を使用します。
例えば、以下のように関数を呼び出します。
myFunction("argument")

スクリプトを実行する前に、必要なライブラリや依存関係がロードされていることを確認してください。
また、スクリプトファイルのパスは、ロードするファイルの場所に応じて適切に変更する必要があります。

やってみた。第 06 章の例である。p.114 にある最初のコードブロックを Rational.scala という名前で保存した。


class Rational(n: Int, d: Int){
  println("Created " + n + "/" + d)
}

次に REPL を起動して、:load コマンドで Rational.scala を読み込ませて Rational が生成できるかどうか確認した。

PS C:> scala
Welcome to Scala 3.2.2 (19.0.2, Java Java HotSpot(TM) 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> :load Rational.scala
// defined class Rational

scala> new Rational(1, 2)
Created 1/2
val res0: Rational = Rational@2a11ae0b

scala>    

うまくいった。さすがは ChatGPT だ。欲をいえば、scala のオプションでファイルを指定するということをしたかったが、 Ver 3 ではできないのかもしれない。https://www.ne.jp/asahi/hishidama/home/tech/scala/scala.html によれば、 scalaコマンドに -i filename というのがあるのだが、これは Scala Ver. 2 時代のようだ。

第 07 章 組み込みの制御構造

p.132 の リスト 7.3 do-while を使って標準入力を読み出す は、Scala 3 ではエラーとなる。

PS C:> scala .\doWhile.scala
-- Error: C:\doWhile.scala:2:0
2 |do {
  |^^
  |end of toplevel definition expected but 'do' found
1 error found
Errors encountered during compilation
PS C:>

これは、Scala 3 で do-while 構文が廃止されたからである。

https://docs.scala-lang.org/scala3/guides/migration/incompat-dropped-features.html#do-while-construct

そのため、Scala 3 でリスト 7.3 を scala の REPL で動作させるには、次のように書き直す必要がある。なお、同じページの [監注] に従い、最初の行を追加している。 また、@main を追加した。

import scala.io.StdIn.readLine
@main def readLine() = 
  var line = "" 
  while ( {{  
    line = readLine()
    println("Read: " + line)
  } ; line != ""}) ()

誤植

https://book.impress.co.jp/books/1119101190 以外の誤植は見当たらなかった。

書誌情報

書名Scala スケーラブルプログラミング 第 4 版
著者Martin Odersky, Lex Spoon, Bill Venners
発行日2021 年 6 月 21 日 初版第 1 刷
発行元インプレス
定価4600 円(税別)
サイズ
ISBN978-4-295-01155-2
その他越谷市立図書館にて借りて読む

まりんきょ学問所コンピュータの部屋Scala > Martin Odersky, Lex Spoon, Bill Venners:Scala スケーラブルプログラミング 第 4 版


MARUYAMA Satosi