Scalaの最も難しいところ

仕事でScalaで書いたプロジェクトを担当する機会がありました。

Scalaは難しい」と時々言われます。

私の感想は やっぱりScalaは難しい

しかし、それはScala大好きな人たちが想像するのとはちょっと違うところ。

sbt が難しい

いろいろありますが、とりあえず Ctrl+C で終了してしまう動作は、初心者の心をくじくと思います。

case が難しい

match節の "case" は「『条件』に合う場合」という意味の "case" ですよね。

では case classは「条件に会う場合のクラス」
???
どういうこと?

多分 case class のは「容器・入れ物」の "case"です。ですが、value class とか struct とか、別な名前にはできなかったのでしょうか?

今は慣れて「Scalacase は単なる目印だ。Lispcarcdr と同じだ」と思うようになりましたが、 なまじ関連がある(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++PythonRubyJavaPHP、Goなどの言語の経験が私の場合はありましたが、 どの言語にも高階関数や代数的データ型の機能が多かれ少なかれ含まれていますから(Scalaほど充実してはいないにしろ)。

つまり、Scalaはどこが難しいか

Scala にはマクロや implicit parameter のような、本当に難解なパーツもあります。でも、大部分(Optionfor、パターンマッチなど)は他言語でも採用されており、それほど難しくはありません。

  • 道具の表面的な部分に粗がある(設計思想自体は別として)
  • 道具の使い方が定まっていない

という、偶有的な難しさが、Scalaは難しく見せてしまっています。

私としては「Scalaクックブック」とか「Scala Good Parts」とか「Scalaコーディング規約」みたいな本があれば、ぜひ買いたいと思っています。