こまどブログ

技術のこととか仕事のこととか。

Scalaに入門してみることにした

先日、下記のようなツイートに接した。

Scalaについては、以前参加したイベントで、コアメンバー(?)らしき方から強く推薦されて、面白そうだなと感じていた。

tddyyx.connpass.com

Scalaというと、JavaやHaskelなどから影響を受けており、JVM上で動く言語だ。冒頭のツイートがそうであるように、Java経験者であれば手を出しやすい(連携できるからという側面もあろうが)というような話を目にすることがある。

僕にとってJavaは、最近は仕事でもプライベートでも書く機会はないが、新人研修でじっくり勉強することのできた言語であり、実際のプロジェクトで書いた唯一の言語でもある。

というわけで、Scalaの勉強を始めてみることにした。関数型のプログラミングを勉強したことがないので、そのあたりも学ぶことができればと思っている。

入門〜環境構築〜Hello World

Scalaに入門しようと思って調べ始めると、下記の記事にまず行き当たった。この手の、情報を集約してくる種類の記事は、自分はおそらく書かないと思うが、存在していると助かることが多いので、それぞれの分野の有識者の方々にはぜひ書いていただきたい。

qiita.com

その中から、評判の良さそうなものということで、ドワンゴさんの新人研修向け資料をまずは読み進めてみることにした。

「新人エンジニア向けの研修資料」という位置付けではあるが、僕が受けた新人研修のように「プログラミング全く未経験」向けのものではないらしい。

読者層としては、

  • 大学の情報学部卒である
  • Java言語の基本知識がある
  • 何か意味のあるアプリケーションを作ったことがある
  • 趣味でTwitter APIなどを触ったり、プログラミングを行っている

人(相当)を仮定しています。なお、上記の指標はこの資料を読むにあたってのあくまで目安であり、特に大学の情報学部卒でなければ理解できないといったことはありません。ただし、本資料は1つ以上のプログラミング言語でアプリケーションを作れることを最低限の前提にしていますので、その点留意ください。

環境構築〜Hello World

環境の構築は、もともとJDKが入っていたので、sbtとIntellij IDEAのみインストールした。この辺りは、研修資料がスクショ付きで非常に丁寧に書かれているので、悩むことなく進めることができた。

テキストに従い、REPLで簡単な出力と計算を行ってみる。まずはお決まりのHello World

println("Hello World")

なるほどJavaを思い出す。ここのところはずっとconsole.log()だったので、少し懐かしい。四則演算も、特に違和感は持たない。

f:id:ky_yk_d:20180819221711p:plain

ここまではよくあるプログラミング入門という感じ。JavaScriptをかじったので、var命令だって怖くない(意味は違うが)。

制御構文の多くが「式」である?

しかし、制御構文の章に入って、雲行きが怪しくなる。

まず、「構文」と「式」と「文」についての説明が入るのだ。プログラミング経験者向けの資料なので、「条件分岐が必要だから〜〜」とif文の説明に入るわけではないのは自然だが、式と文の違いを意識させることに意外の念を持った。制御構文の章の冒頭に置かれたこの説明の末尾には、以下のような記述がある。

ScalaはCやJavaなどの手続き型の言語に比べて、文よりも式になる構文が多いです。 Scalaでは文よりも式を多く利用する構文が採用されています。これにより変数などの状態を出来るだけ排除した分かりやすいコードが書きやすくなっています。

式になる構文が多いと言いながら、この章で出てくるのはどいつもこいつも式である。下記すべて、Javaにも存在するものだが、Javaでは文(つまり、値を持たない)であるのに対し、Scalaでは式(つまり、値を持つ)であるという。

  • {}
  • if
  • while
  • for

特に、forについては、Javafor文におけるのとは異質な使い方をすることができるようである。

実は、for構文はyieldキーワードを使うことで、コレクションの要素を加工して返すという全く異なる用途に使うことができます。特にyieldキーワードを使ったfor式を特別に for-comprehensionと呼ぶことがあります。

これらが式であるということは、おそらく、関数型プログラミングにとって重要な特徴なのではないだろうか。これから勉強を進めていく中で、明らかになるだろう。

match式、パターンマッチ

制御構文の章の後半は、match式の導入である。Javaswitchが引き合いに出されているが、かなり申し訳程度であると感じた。Javaswitchは、(OOPの立場からは)隙あらばポリモフィズムによる書き換えの対象となるような代物だ。それに対して、Scalaにおけるmatchは、極めて強力な機能を持っているようだ。

match式の説明の部分は、下記のような項目に分けられている。

  • パターンをまとめる
  • パターンマッチによる値の取り出し
  • 中置パターンを使った値の取り出し
  • 型によるパターンマッチ
  • JVMの制約による型のパターンマッチの落とし穴

説明に一通り目は通したが、どうにも頭に入ってこない。正直に言って、この段階で既にJavaとだいぶ違うというので少々面食らっている。先達(この方も元々Javaプログラマで、Scalaを後から勉強された方だったと思う)も、下記のようにツイートしていて、どうも関門のようだ(このツイートで言われているのはもっと高度な話だと思うが)。

思ったこと

上にも既に書いたが、ここまでJavaと違うとは思わなかった。いや、違うというのはわかっていたが、違いが出てくるのが思ったより早かった。JavaScriptはよく、「Javaと名前は似ているけど全然違う」と言われるが、JavaScriptを勉強し始めたときとは全くレベルの異なる戸惑いを感じている。

とはいえ、言語として違いがあるということは、それだけに学ぶことの意義も大きいということだ。自分がオブジェクト指向をマスターしているとは口が裂けても言えないが、それとは違うパラダイムを学ぶことは意味のあることだと確信できるし、何より面白い。

ボブおじさんも、下記のように言っている。オブジェクト指向関数型プログラミングの両方を身に付けることは、単にプログラマとしての幅を広げたり、書き方の参考にすることができるようになったりというだけでなく、両方を駆使したプログラミングを可能にするということなのかもしれない。