仕事でScalaで書いたプロジェクトを担当する機会がありました。
「Scalaは難しい」と時々言われます。
私の感想は やっぱりScalaは難しい。
しかし、それはScala大好きな人たちが想像するのとはちょっと違うところ。
sbt が難しい
いろいろありますが、とりあえず Ctrl+C
で終了してしまう動作は、初心者の心をくじくと思います。
case
が難しい
match節の "case" は「『条件』に合う場合」という意味の "case" ですよね。
では case classは「条件に会う場合のクラス」
???
どういうこと?
多分 case class のは「容器・入れ物」の "case"です。ですが、value class
とか struct
とか、別な名前にはできなかったのでしょうか?
今は慣れて「Scalaの case
は単なる目印だ。Lispの car
・cdr
と同じだ」と思うようになりましたが、
なまじ関連がある(case class は match 節の条件に)ものに同じ字面の "case" を使っているために、初心者を当惑させます。
for
と .map
と .fold
の使い分けが難しい
「Optionの中身に関数を適用、ただしOptionが空の場合はデフォルト値」という処理を書くにはどうすればいいか。
等価な処理を、大差ないコード量で、for
でも .map
でも .fold
でも書けます。
(for (account <- maybeAccount) yield { account.name + account.title}).getOrElse('名無しさん')
maybeAccount.map { account -> account.name + account.title }.getOrElse('名無しさん')
maybeAccount.fold({ '名無しさん'}, { account -> account.name + account.title })
複数のOptionやSeqを取る場合にも使えるから for
にするのか、よく使うからmap
なのか、コード量が少ない .fold
なのか、
悩んで脳のリソースを奪われました。
ついでに、レビューで「このパッケージでは for
で統一している」派と「アプリ全体では map
が主流」派の対立も起き、時間的リソースも奪われます。
異常に引数が多いメソッドを作る同僚との付き合いが難しい
Rubyなどと違い、Scalaではメソッド引数に型を指定できたりするため、引数の個数が増えてもあまり苦になりません。
しかし、コードレビューの際に引数が10個もあるメソッドを見たとき、そしてそれを書いた奴に 「Rubyなどと違い、Scalaではメソッド引数に型を指定できたりするため、引数の個数が増えてもあまり苦になりません。」 と言われたときなどに、プログラマーは多大なストレスを感じる可能性があります。
関数型言語自体は別に難しくなかった
戻り値が Option[Hoge]
だったりしても別に驚きませんでしたし、
for文にOption型を使えても「Scalaは徹底しているな。役に立つのかわからないけど」くらいにしか思いませんでした。
C++、Python、Ruby、Java、PHP、Goなどの言語の経験が私の場合はありましたが、 どの言語にも高階関数や代数的データ型の機能が多かれ少なかれ含まれていますから(Scalaほど充実してはいないにしろ)。
つまり、Scalaはどこが難しいか
Scala にはマクロや implicit parameter のような、本当に難解なパーツもあります。でも、大部分(Option
、for
、パターンマッチなど)は他言語でも採用されており、それほど難しくはありません。
- 道具の表面的な部分に粗がある(設計思想自体は別として)
- 道具の使い方が定まっていない
という、偶有的な難しさが、Scalaは難しく見せてしまっています。
私としては「Scalaクックブック」とか「Scala Good Parts」とか「Scalaコーディング規約」みたいな本があれば、ぜひ買いたいと思っています。