ScalaスケーラブルプログラミングをScala2.8RC1で読む その1
実は一気読みしようと思っていたのですが、全く進んでません…関数型言語なめてました。そんなわけで第一弾です。
本書はScalaバージョン2.7.2をベースにしたScala言語の解説書です。
一方、現在のScalaの最新バージョンは2.7.7で、次バージョン2.8のRC1もリリースされている状況です。また、IDEのプラグインの対応についても、NetBeans6.8では2.8RC1向けのもののみ存在し、Eclipseについても2.8向けのプラグインの出来の方が2.7向けのものより良いという話を聞きます。
ですので、せっかくなんだから2.8RC1で始めるのが良いのではないかと考え、その上で詰まったところ等をメモしていこうと思っています。
…って、公式サイト確認したら先程RC2リリースされちゃったみたいですが。
参考サイト
TIPS
TIPS、といっても1点だけなんですが。コードを打ち込む際、scalaコマンドでインタプリタを起動して直接タイプするとtypoしたとき悔しい思いをすることになります。それを避けるため、コードはファイルに保存し、インタプリタ上では :load <ファイル名> コマンドでロードすると良いかと思います(ちなみに私はコマンドにコロンを付け忘れていてはまりました)。
2.7.2からの変更点
11章(p.202)までしか読めていませんので、その範囲で。
初っ端でコンパイルが通らなかったので色々変わっているのかな、と身構えていたのですが、どうやらコンパイルエラーになるのはこの1点だけのようでした。
p.68 リスト3.10, p.128 リスト7.8, p.142 リスト8.1, p.144 リスト8.2で登場する、
は、2.8では
というメソッドに変更になったようです。
その他、コンパイルエラーになるわけではないですが、気づいた変更点を。
p.103 表5.5
scala.runtime.RichStringクラスは無くなっています。p.90で出てきたstripMarginメソッドみたいなものは、実はscala.collection.immutable.WrappedStringクラスのメソッドになっているようです。(こういう点が「下位バージョンとバイナリ互換性が無い」という理由なんでしょうか。)
p.135 7.6節 breakとcontinueを使わずに済ませる
Scala2.8ではbreakが導入されたそうです[参考]。
p.183 10.9節 多相性と動的束縛
Array.makeメソッドはdeprecatedになり、コンパイル時に警告が出ます。
Array.make(height, line)
は
Array.fill(height)(line)
とするようです。
p.187 10.12節 above、beside、toStringの実装
Elementクラスにaboveメソッド
def above(that: Element): Element =
new ArrayElement(this.contents ++ that.contents)
を追加すると、前述TIPSで記述した:loadコマンドを使う方法では、型が違う、と怒られてしまいます。:loadコマンドの出力を見る限り、クラスの定義は1つずつ認識しているようなので、ElementとArrayElementが継承関係であることを認識できない、つまりクラス定義内ではアップキャスト不可、ということになります。(事前にArrayElementクラスの定義をしておき、Elementクラスをextendsしていることを明示していてもNGでした。つまりこの動作はクラス定義の順に依らない。)
普通にscalacでコンパイルすると通りますので、こういったものについてはインタプリタではなくscalaコマンドでの実行が必要みたいです。
感想・疑問点など
上で登場したgetLinesメソッド、なぜgetLinesの後に”()”が必要なのでしょうか。本書p.93には、”後置演算子は、ドットや括弧を付けずに呼び出される引数なしのメソッドである。Scalaでは、メソッド呼び出しの空括弧を省略できる”とありますので、省略できそうに思われるのですが。
と思い、APIドキュメントを見てみると、引数が無い(ように見える)メソッドには3つのパターンがあるようです。
- RichInt#toString() のように、後ろに括弧がついているもの - 空括弧メソッド(empty-paren methods)
- RichInt#toHexString のように、後ろに括弧がないもの - パラメータなしメソッド(parameterless methods)
- Source#getLines(separator: String = scala.compat.Platform.EOL) のように、引数を取るがデフォルト値があるもの
上述した引用文は、このうちパターン1.について述べているようです。toStringは括弧有りでも無しでも動作しました。一方、パターン2.は括弧をつけるとコンパイルエラー、パターン3.は括弧をつけないとコンパイルエラーになります。
括弧の省略をOKにするのならば、上記全てのパターンにおいて括弧つけてもつけなくてもOK、というのが統一的な動作であると思うのですが、何か意図があるのでしょうかね。ちなみに、パターン1.と2.のどちらを用いて実装すべきかの指針はp.174 10.3節『パラメーター無しメソッドの定義』で説明されています(が、toStringとtoHexStringの例を見る限り、あんまり統一されてないのかな、とも思います)。
諸々:
- インタプリタで関数を定義した時の出力(引数の部分の表示)が変わっている。
- セミコロンが省略できたりできなかったり、小括弧”()”が省略できたりできなかったり、小括弧の代わりに中括弧”{}”が使える箇所があったり、書いたり読んだりするのに慣れが必要そう。
- <- とか => とかタイピングしにくい…マイナスとイコールってShiftキー押すか押さないかだからしょっちゅう間違う。JISキーボードと相性悪いぞこれ。
- 行末のアンダーライン”_”を見るとVBを思い出しますね。用途は全然違いますが。
- Javaとの互換性というか整合性というか、そういう部分については、ScalaよりGroovyの方が重きをおいて言語仕様考えてるんだろうな、というふうに見えます。
- 部分適用とカリー化が別物、というのは理解しましたが、Groovyのは部分適用であってカリー化じゃないだろ、っていう辺りはまださっぱりです…
« ループ内で変数を宣言しない方が良いのか | トップページ | さきゅばすのNicoBrowser拡張 1.4.2 アクセス先URL変更(暫定)対応 »
この記事へのコメントは終了しました。
« ループ内で変数を宣言しない方が良いのか | トップページ | さきゅばすのNicoBrowser拡張 1.4.2 アクセス先URL変更(暫定)対応 »
コメント