コードを読み込みScalaの関数型パラダイムを学ぶ - xuwei-kがScalaを学ぶために読んだOSS

数多くのScala関連OSSにコミットを続ける吉田憲治(xuwei-k)さん。その精力的な活動を支える、関数型の知見の源をうかがいました。

コードを読み込みScalaの関数型パラダイムを学ぶ - xuwei-kがScalaを学ぶために読んだOSS

オブジェクト指向言語と関数型言語の特徴を併せもつマルチパラダイム言語・Scala。この言語に関連するOSSのコミット履歴には「1xuwei-k」というアカウントが頻繁に登場します。今回お話を聞いた吉田憲治(よしだ・けんじ/ 3@xuwei_kさん、その人です。

吉田さんはScalaのスペシャリストとして、数多くのScala関連OSSにコミットを続け、2018年、Scalaコミュニティに対する貢献者に贈られる「Phil Bagwell Award」を受賞しています。界隈屈指のコントリビューターとして知られる吉田さんに、Scalaのスキルを研鑽してきた過程や、この言語を使いこなすための秘訣について伺いました。

3

2009年に大学卒業後、新卒入社したIT企業で組み込みC言語プログラミングに携わることから、エンジニアとしてのキャリアを開始。転職後、業務でScalaを扱うようになったことから、この言語を本格的に学ぶように。多数のScala関連OSSへのコントリビューションを行っており、Scala本体やビルドツールのsbtなどのコミット権限を有する。ブログ:xuwei-k's blog

当時の自分には、OSSのコードを読む以外の選択肢がなかった

——吉田さんはいつ頃Scalaと出会われたのでしょうか?

吉田 『Scalaスケーラブルプログラミング』という書籍が10年ほど前に日本語に翻訳されたのですが、その本をたまたま手にとったことがきっかけです。僕は当時、社会人1年目でしたから、エンジニアとして仕事をするようになって、早い段階でScalaと出会いました。

その頃は、まだScalaに強くコントリビューションしていたわけではなかったのですが、その後、転職をしたくらいのタイミングで本腰を入れて学ぶようになったんです。新卒で入った会社では組み込みでC言語を書いていましたが、転職先ではScalaを書くようになったので。その後も何度か転職をしていますが、業務ではずっとScalaを書き続けています。

——Scala関連のOSSに携わるようになったのはどうしてですか?

吉田 いまと違って、当時はまだまだScala関連の日本語ドキュメントの数が少なかったんです。各種ライブラリの使い方や良いScalaコードの書き方を学ぼうにも、日本語でアクセスできる情報がほとんどない。日本人のScala界隈で有名な人に質問するにしても、限度がありますから。

それに、かつて僕は英語にも苦手意識があって。読むのはギリギリなんとかなるとしても、英語で質問するのは、ちょっと難しい。だから、英語を読むよりもソースコードを読むほうがまだいいなと考えて、OSSのコードに触れるようになりました。僕の場合は特殊なケースだったので、同じ学習法をいまの若いエンジニアの方にはおすすめできませんが(笑)。

読んでいくと、細かい不具合やtypoがよく見つかるんですよね。そこで、直したいと思ってPull Requestを出す。それがコントリビューションのスタートでした。

その後、関数型プログラミングのライブラリであるScalazにもバグフィックスなどのコントリビューションするようになっていきました。特定のファイルでコンパイルエラーが発生していたので、その修正をしたんです。

Scalaz特有の文化なのか、牧歌的な時代だったからなのかはわからないですけど、Pull Requestを発行せずにメインのブランチに直接pushする方もいて。それが原因で特定の機能が壊れていることがよくあったんですよ。

その頃はCIツールもそれほど普及していなかったので、エラーを検出できませんでした。そういった不具合を直すことからOSSへのコントリビューションを始めていきました。

「わからなすぎる」からこそ興味を持った関数型のパラダイム

——Scalaはどのような特徴を持つ言語だと考えられますか?

吉田 特徴はいくつもあるから難しいですが、あえて挙げるなら、やはりオブジェクト指向と関数型の両方を併せもつ言語であることですね。Scalaの作者であるマーティン・オダースキーは、両者の特性を組み合わせたときに真価を発揮する言語としてデザインしたようです。

しかし、作者の意図がすべてのユーザーに伝わっているかと言うと、そうではなくて。OSSのライブラリ界隈でも、極端に関数型に寄っている方々と、そうでない人たちもいます。Scalaのコーディングは、ユーザーによってかなりスタイルが分かれていると感じますね。

4

——関数型に寄っているOSSとしては、何が挙げられますか?

吉田 先ほど名前が出たScalazは一例として挙げられます。Scalazはいまでこそ開発が下火になって、ほとんど僕しかコミットしていないですが、かつてはScalaで関数型を扱うためのデファクトスタンダードといえるライブラリでした。Haskellにあるような型クラスやデータ構造を、可能な範囲でScalaに翻訳したようなつくりになっています。

Scalazに触れ始めたころは、あまり関数型についての理解がなく、コードを読んでも意味が全くわからなかったんですよ。ただ、わからなすぎて逆に興味がわいてきた(笑)。「どういう意図でこういうつくりになっているんだろう」と考え始めると面白くなってきて、読み進めていました。関数型のパラダイムを学ぶうえで、Scalazはかなり役に立ちましたね。

当時はScalazを解説している記事もなかったですし、Scalaz本体にもドキュメントはほとんど書かれていませんでした。情報源があるとすれば、機能の元ネタになっているHaskellの情報を学ぶしかない。だからHaskellも勉強するようになっていったんです。

——今の時代に関数型を学びたいという若手がいるとしたら、同じ勉強法をすすめますか?

吉田 正直、僕のやってきた勉強法はめちゃくちゃ体力がいるので、もっと楽をすればいいと思います。関数型を解説する書籍も充実してきましたから。例えば、Scalazに関わっていた方々が書いた『Scala関数型デザイン&プログラミング』を読んでみるといいのではないでしょうか。

——関数型の特徴が顕著なOSSは他にありますか?

吉田 極端に関数型の要素が表れているライブラリとしては、effなども挙げられます。実はちょうど(取材実施の)前日にこのライブラリのコミット権限をもらったので、直近は僕のコミットが大量にありますね。

——これは何を実現するライブラリなのでしょうか?

吉田 Extensible effectsと呼ばれる概念をScalaで実現するためのライブラリです。Haskellの世界では、モナドと呼ばれるパーツを組み合わることで処理を実現します。別の種類のモナドを組み合わせるにはモナド変換子と呼ばれるものが必要になりますが、Extensible effectsはこのモナド変換子に近い機能を実現するための概念のひとつになります。

極端に関数型っぽいコーディングスタイルを用いる必要があるので、使用の難易度もなかなか高いです。初学者の方ですと、コードを読んでも何をやっているか理解しにくいかもしれません。

import org.atnos.eff.all._
import org.atnos.eff.syntax.all._

// useful type aliases showing that the ReaderInt and the WriterString effects are "members" of R
// note that R could have more effects
type _readerInt[R]    = ReaderInt |= R
type _writerString[R] = WriterString |= R

def program[R :_readerInt :_writerString :_eval]: Eff[R, Int] = for {
  // get the configuration
  n <- ask[R, Int]

  // log the current configuration value
  _ <- tell("the required power is "+n)

  // compute the nth power of 2
  a <- delay(math.pow(2, n.toDouble).toInt)

  // log the result
  _ <- tell("the result is "+a)
} yield a

// run the action with all the interpreters
// each interpreter running one effect
program[Stack].runReader(6).runWriter.runEval.run

https://atnos-org.github.io/eff/org.atnos.site.Introduction.html よりコードを抜粋。

こういった書き方を実務で用いることは稀でしょうが、「関数型っぽいコード」の参考にはなるかと思います。

——実務でScalaを使う場合には、どのような基準で「オブジェクト指向的な書き方」と関数型的な書き方」のバランスをとるべきでしょうか?

吉田 コーディングスタイルは書き手のスキルに依存するので、「チーム内にどのようなメンバーがおり、各人がどれくらいのScalaないし関数型の知識を持っているか」に応じて考える方がいいと思います。

もし、チーム内にさまざまなスキルレベルの人がいる場合には、ある程度のコーディング規約を決めておく方が、面倒が少ないのではないでしょうか。Scalaはオブジェクト指向の色合いが強い書き方も、関数型の色合いが強い書き方もできるので、どちらのスタイルでもいけてしまうところがあり、エンジニアがあまりに自由にやりすぎると、収拾がつかなくなる可能性があります。

関数型を使うことで効果的なコーディングになるならばいいですが、誰も使いこなせないのであれば使っても意味がないですし、逆効果でさえあります。バランスを取りながら使う方がいいと思います。

Play Frameworkやsbtをうまく活用するために

エンジニアHubに会員登録すると
続きをお読みいただけます(無料)。
登録のメリット
  • すべての過去記事を読める
  • 過去のウェビナー動画を
    視聴できる
  • 企業やエージェントから
    スカウトが届く