Scala自習(その1)
以前のエントリで、『Scalaスケーラブルプログラミング』(以後:Scala本)をナナメ読みしたとか書いた。
しかし所詮はナナメ読み。頭の中に入って血肉になっているかと言われると非常に疑問。というか、全部読むのに1週間しかかかってない時点で、全内容の何割に手を付けたやら怪しいものである。
モノゴトは文章にまとめると理解が進むらしい。そこで、何回分かのエントリを使って自習内容を復習し、まとめることにした。
基本的に自分用なので、「前提知識はオレオレ」状態になっている。書き方もざっくり。一応パブリックな書き物でそりゃどうかと思わなくもないけど、まるまる説明する見識も技術もないのでやむをえない。
内容に誤りがあるかもしれない。
その1って書いてあるけど、続くかは分からない。
Scalaとは
Javaに続く(?)次世代のプログラミング言語として近年期待されている言語。Scala(スカラ)という名称は、「スケーラブルな言語」に由来する。つまり
- スクリプト的な小規模プログラムが容易に記述できる
- 大規模なプログラムにも対応する
- 小規模なプログラムが、大規模なプログラムに変化することを支援する
ということ。言語仕様として
- 静的型付け+型推論
- オブジェクト指向言語と関数型言語の統合
- その他、細かな改善
などを盛り込んでいる。
Scala本の対象読者
「プログラミングについての一般的な知識は必要」とする一方で「特定のプログラミング言語についての具体的な知識は不要」としている。
個人的にはやや疑問。少なくともオブジェクト指向言語か、関数型言語どちらかの経験は必要だと思う。Scalaは頑張って二つを対等に統合しようとしているので、はっきり言って二つがバラバラの時よりも言語の複雑さが増している。
オブジェクト指向をサポートした言語(C++/Java/C#など)か、関数型言語(Lisp/ML/Haskellなど)の前提知識が欲しい。関数型の概念を取り込んだ比較的新しい言語(Python/Ruby/C#3.0など)を知っているのも役立つと思う。
対話環境
手探りでコードをいじるのが自習には一番良い。対話環境があればレスポンスがすこぶる良くなるので、もっと良い。もちろん、Scalaにも対話環境がある。
言語の基本要素
/* Comment */ 1 + 2 // Int "String" val i = 3
※はてなダイアリーのシンタックスハイライトが現時点でScalaに対応してないっぽいので、Javaのもので代用した。
変数代入の構文は
val 識別子 = 右辺
あるいは
var 識別子 = 右辺
になる。Scala処理系は、右辺の型から変数の型を推測してくれる(型推論)。例えば上の例の場合、右辺がInt型リテラルの3であるから、変数iはInt型である。
valは変数への再代入を許さないが、varは許す。再代入(状態の変化)は一般的にコードを複雑にしてしまうが、変化を認めたほうが自然に記述できるケースもある。また効率の観点から、varを使わざるをえないケースもあるだろう。
その行だけで意味が通る限りにおいて、コードは行ごとに文が一つだと解釈される。ただし次のように一行が不完全な場合*1は、複数行に文がまたがっていると解釈される。
1 + 2 + 3
C系言語のように、文末にセミコロンは必要ない(セミコロン推論)が、一行に複数の文を書く場合は、文の区切り文字として必要である。
1 + 2; println("hello"); 2 * 3
printlnは渡された文字列を出力した上で、改行文字を出力する。この例を評価すると何も値が返ってこない。値を返すのは式だけ?
制御構造
var i = 1 while (i < 100) { if (0 == i % 15) println("FizzBuzz") else if (0 == i % 5) println("Buzz") else if (0 == i % 3) println("Fizz") else println(i) i += 1 //いわゆるインクリメント演算子は無い }
C系の言語ではおなじみの制御構文。動作もほぼ同じだと考えていいようだ。ただし、これらは文ではなく式。つまり、制御構造も値を返すので
val a = 5 val b = 8 val c = if (a < b) b else a // c = 8
こんな記述も認められる。
*1:開き括弧に対応する閉じ括弧が無い場合や、次の行が不完全な文法になっている場合も同様