Scalaへの移行 -ウォルマート・カナダへの導入で学んだこと-
はじめに
Scalaについて皆さんどんなイメージを持っていますか?
よく、難しい、変態言語、関数型言語が難しい、といった声を聞きます。
一方でScalaを使う人達はそれを絶賛しますし、別に皆が本当に関数型を理解しているわけではありません。
私もその一人です。
では真実はどちらなのでしょう。
今回はScalaの導入時の体験記としてウォルマートでの導入で学んだことについての記事を翻訳しました。
Transitioning to Scala - RedElastic
作者はLightbendで働いた経験もあるScala導入のプロです。
なお記事自体は2014年のものなので、現在とは多少環境が違うこともあるかもしれませんが、筆者の体感としては大きく間違ったことは書いていないと思います。
この記事がScalaの実態を知りたい人、導入に迷っている人の役に立てれば幸いです。
2011年の終わりから2014年のはじめにかけて私はNurun Torontoのリード開発者で、その会社はeコマースのソリューションにフォーカスしていた。
JavaとSpringフレームワークのプロジェクトが進行するにつれて別の方法をすぐに探さなければならないという思いに駆られるようになった。
広い観点から考えることが必要になったのだ。
「Javaはクソ」という言葉は客には響かず、納期は破られる。
アプリケーションをビルドするためのツールは2004年製で、2014年にはなんの役にも立たない。
2004年には一行のコードをテストするためにサーバーを再起動することは全くもって問題ないことだった。
WebSphereは再起動に平均120秒かかる。
その時間はコーヒーを飲みながら1200行のXMLファイルとにらめっこするのにちょうどよかった。
今はそんな企業も開発者も廃業した。
もはやアプリケーションはデータベースの前に居座るうすっぺらな何かではなく、日々の生活に欠かせない貴重なものだ。
Why the Typesafe stack?
Ruby on Railsで過去実装したことがあるが、その時悟ったことがある。
もう動的型付けインタプリタ言語、ステートフルなwebフレームワークはごめんだ。
静的型付けでJavaバイトコードにコンパイルされる言語がほしい。
もちろんスケーラビリティのためにはツールのエコシステムとステートレスなフレームワークも欠かせない。
顧客の心の安寧のために信頼できるベンダーによる専門家のサポートが必要だろうこともわかってる。
2、3選択肢はあったが、直感的にTypesafe stackを選んだ。
必要なものをすべて備えていたのだ。
Scalaの簡潔さとPlayの開発効率のデモとして内部的に作ったマイクロeコマースサイトはPOCとして始まり、支持を集め最終的にはウォルマート・カナダのeコマースプラットフォームになった。
Why is Scala perceived to be complex?
Scalaは柔軟だ。
それは簡潔さを犠牲にするが、一方でScalaはただの「better Java」である以上にエレガントだ。
Scalaへの移行(どんな移行もそうだが)における最大の挑戦は技術的なものではない。
優秀なプログラマにとって新しいシンタックス、概念、IDEなど造作もない。
それよりも変化はプロセスやカルチャーにおける弱さを露呈する。
tl;dr — 言ってしまえば人間に関わる全て
この記事の残りはScalaのチュートリアルではない。
そんなものはもう沢山あるし、Scalaの最新のトリックについてScalaの深淵を踏まえつつ教えるのには私より適任がいるだろう。
この後はScalaへの移行を考えているチームの開発者、マネージャー、チームリーダーに向けて書いていく。
アドバイスはエンタープライズのSclaプロジェクトにおける個人的な経験に基づいている。
Advice for developers and managers thinking of making the switch to Scala
1. Understand the language features
Scala開発者、チームリーダー、マネージャーはMartin OrderskyのScala levels: beginner to expert, application programmer to library designer | The Scala Programming Language
を読むべきだ。
1年半のフルタイムScala開発者として、またエンタープライズでのScalaプロジェクトの経験から、私はA2.5/L1.5レベルのScala開発者と言っても差し支えないだろう。
A3/L3に書いてあるテクニックも使ったことはあるが、webアプリケーションを作るという比較的カンタンなタスクでは使用する必要はあまりない。
Higher-kinded typeを学ぶためにcake patternを使ったこともある。
これで悪いプログラマになることもないし、インポスター症候群のひどい症状、つまり劣等感に見舞われることはない。
時間は限られているのだ。
大金を稼ぐために必要なことにフォーカスする必要がある。
ドラムやギターも弾きたいし、週に二回ダンスレッスンも行ってる。
沢山コーヒーも飲むしデートにも行きたい。
時間は貴重だ。
ウォルマートプロジェクトではパーサーコンビネーターとfoldsに加えて、levelガイドの簡単な方だけを使用することにした。
簡単とは言っても、リプレイス前のものよりも非常にいいものだった。
実装で頭を抱えることもなくなった。
リプレイス前と比べて無限にメンテナンス性は向上した。
実行時には非常に早く動く。
Black FridayやBoxing Dayでも完璧にスケールする。
Javaのシステムでは不可能なことだ。
すごいだろう?
だからシンプルなScalaを劣ったものと思うのは間違ったことだ。
レベルA1とA2で学べるのは以下のようなものがある。
- 単純なクロージャ
- コレクションとmap, filterなど
- パターンマッチング
- traitの合成
- 再帰
- XMLリテラル
こういった長所でJavaを超えることができる。
メンテナンス性に優れ、表現力豊かなソフトウェアを作る新しい方法だ。
A3のいくつかの技術も習熟がけっこう簡単だ。
特に、Akkaや並列コンピューティングを使用するときに非常に重要だ。
挫折するほど難しくはないし、数学の知識が必要になることもない。
- Folds
- Streams and other lazy data structures
- Actors
- Combinator parsers
副次的にすべての言語においてより良いプログラマになることができる。
これは喜ばしいことだ。
クロージャや他の技術を取得したことによって今や非常に優れたJavaScriptエンジニアにもなることができた。
2. Take your time
Java畑から来た人はScalaによる即座の成果を求める。
だけどScalaがJavaとは全く別の言語だということは理解していない。
新しいものに習熟するには常に訓練が必要だ。
Scalaもその例外ではない。
喜ばしいことにA2/L1レベルのScalaエンジニアは普通のScalaアプリを書けるほどに十分習熟している。
若い開発者のメンターさえできるだろう。
すべてのScala開発者が純粋関数型志向のデータ型、型理論、higher-kinded typeを理解する必要はない。
Scalaは次世代のアプリケーションを作るためのプロ向け言語だ。
学ぶには時間がいるし、習熟するにはもっと時間が必要だ。
3. Don’t be afraid to study
もしあなたがJava開発者なら以下の順で学ぶことは強く推奨する。
- Scala for the Impatient。命令型言語の使用者にとってのスタート地点、とくに練習問題は必ずやったほうがいい。私もなにか困ったときはその回答を見直すことがある。
- Programming in Scala(日本語版: Scalaスケーラブルプログラミング)。上の本よりも詳しく、言語機能について大雑把に知った後に読むと良い。
- できることならFunctional Programming Principles in Scala | Coursera。Coursera自身もScalaを使用しているのだ!
- Get Started with Lightbend Technologies | Lightbend Tech Hubを覗いてみよう。他の言語に比べてScalaはオンラインの教材が少ない。しかし誰かのコードをハックする以上に学びとなることはない。特にそれがJames Wardのような優秀な開発者によって書かれていたものならなおさらだ。
- Functional Programming in Scala | Coursera。これは大容量のデータを処理するためAkkaを使用する人にとっては最高の教材だ。
- Scalaのミートアプに参加し、他のプログラマがどうやってScalaを使用しているか学ぼう!
- Functional Programming Patterns in Scala and Clojure: Write Lean Programs for the JVM。命令型のコードに対し、関数型の可読性の高さを実感してから関数型言語をどうしても学びたくなった。Haskellはちょっと重い、だから私はClojureを学んだ。私のScalaコードはすぐさま完結で意味の伝わりやすいものになった。
4. Take what you read online with a grain of salt
Scalazの作者であるTony Morrisなどは信じられないくらい優秀で、私とは違いHaskellや関数型プログラミング、数学をバックグランドとしている。
彼は下の2つのシグネチャのうち後者を好む。
def revese[A]: List[A] => List[A]
def <-:[A, B](f: A => B): List[A] => List[B]
そして以下の用に主張する。
次に
<-
という関数を見たらきっと「可読性悪いな、何したいかわからないよ」と思うかもしれない。
しかしよく知っているものよりなにかロバスト性があるのではないかと考えてみることがコードを理解するには大切だ。
どんな型か?代数的性質はなんだろう?有益なパラメトリックな性質は無いだろうか?
これこそがScalaの美しさだ。
Tonyは正しい。
そして私も正しい。
別に間違ったことは言っていない。
個人的、そしてチームの好みの問題だ。
私はreverseの方を好む。
だけどTonyのような開発者は数学の純粋さと真実性を強く求める。
同時に私は簡潔さと可読性を好む。
スタイルというものは人によって異なるものだ。
Tonyはライブラリーを書き、私はライブラリーを使用してアプリケーションを書く。
そして私達は各々の目的のためにScalaを使っているのだ。
私は時にはvarを使用し後できれいにすることを厭わないが、それは他の誰かにとっては間違ったものに感じられる。
しかし仮にチームが英語やフランス語、ドイツ語など様々な言語を喋っているとしよう。
そのような場合には英語より記号を使ったほうが理解しやすいだろう。
だからこそScalaのような一つの書き方を強制しない言語は美しい。
どんなスタイルでも適用可能だし、それを言語は邪魔しない。
<-:
が定義可能であることは愛すべき点だ。
5. Leverage professional services if within your budget
Typesafeの開発者であるNilanjan RaychaudhuriやRoland Kuhnのの力を借りられたのは非常に幸運なことだった。
彼らはNurunが設計やコードのレビュー、ペアプログラミングのために参加させた。
私達が新しいスタイルのプログラミングを学ぶ上において、彼らの補助は様々なフェイズで私達の自信に寄与した。
それは計り知れない価値だった。
関数型指向のScalaを学ぶだけではなく、リアクティブプログラミングについて学ぶこともできた。
博打で新たな技術に手を出すときにTypesafeの補助があったのは大きな助けになった。
正しい道を進んでいるという大きな自信になったのだ。
Typesafeのemailサポートは非常によく応えてくれる。
Lightbend Platform Subscription | @lightbendも予算の許す限り、その費用に見合うものになるだろう。
6. Embrace diversity
Scalaコミュニティは世界で一番様々な種類のプログラマで構成されている。
Javaエンジニアだった人もいれば、学術の世界から出てきた人もいる。
独学のエンジニアもいれば、博士号を持っている人もいる。
厳しい予算の野中ビジネス上の課題を解決しようとしている人もいれば、計算機科学の未踏の地へ踏み込もうとしている人もいる。
アプリケーションを構築している人もいれば、ライブラリを書いている人もいる。
いい開発者になるにはコミュニティの人々をリスペクトすることが大事だ。
StackOverflowに投げられたシンプルな質問についた難解な回答を理解するには何年も圏論を勉強がある必要があると思うかもしれない。
しかしScalaは新しい言語で、コミュニティはどんな質問でも欲している。
学術出身でないプログラマが増えていくにつれ、議論や回答はだんだんアプリケーションにフォーカスしたものになっていくだろう。
自信を失ったならGitHub - twitter/finagle: A fault tolerant, protocol-agnostic RPC systemやGitHub - mDialog/smoke: Simple, asynchronous HTTP using Scala.を見てみるといい。
FinagleとSmokeは本番環境で使用されている最も美しいScalaの例だ。
すべてのScalaコードが飛び抜けて複雑なわけではない。
7. Set realistic expectations
Java出身のScala新米エンジニアは応用的な関数型Scalaを徹夜で学ぶ必要はないということを理解すべきだ。
同時にアプリケーションを書くときにそのようなScalaが必ずしも必要というわけではない。
Scalaは関数型をもともと推奨しているから関数型のバックグラウンドを持つ人は適応しやすいだろう。
でももしチームのほとんどが命令型の言語出身ならそれに合わせる必要はある。
チームのバランスというものが最も大切で、チームの人にとってメンテナンス性が優れているということを保証しなければならない。
メンテナンス性が低く素晴らしくエレガントなコードはまったくもって役に立たないものだ。
8. Pair programming and code reviews are mandatory
ペアプログラミングはチーム内でコードスタイルがばらつかないように必要不可欠と言ってもいいだろう。
普通のプログラマが触れられないほどの応用的なコードを書いたり、ただ一人の関数型プログラマが完璧に動く命令型コードを書き換えるのは最後にやることだ。
実験というのは大事で、そのためにGitはある。
Forkをしようね。
Scalaというのは非常に柔軟で、複雑で誰も知らない領域まで行ってしまうのは簡単だ。
そこでScalaの絶大なパワーを解放し新たな機能を探索することもできる。
カルチャーというものは開発チームにとって非常に大事で、新しくScalaを学ぶチームにとってより重要なのは協調して動くことだ。
9. Keep it simple
Scalaは新しい言語で、使用すべき機能とそうでないものについての議論は今も続けられている。
チームにおいて最適な言語というものは議論の余地があるのだ。
絶対的な正解も不正解も無い。
試行錯誤し、意味のわからないものについては積極的に質問しよう。
Reflection APIがJavaに導入された時、Javaエンジニアは皆知的専門性を高めようとそれをなんにでも使ったものだ。
結果当時私が開発していたコードベースの一部は運用において悪夢を見ることになった。
一人の狂った開発者が言語機能を理解もせずに乱用した結果だ。
Scalaを書き始める時は不明瞭な言語機能に鼻を突っ込むよりも、きれいにゆっくりと始めるほうがいい。
私はいつになっても応用的なメンテナンス性に劣ったScalaよりも命令型のScalaの方を好むだろう。
いい音楽がそうであるように、良いコードもまたエレガントで整っているものだ。
美味しいものは少しのいい材料からできている。
誰も想像出来得る限りすべてのスパイスを効かせた粥など食べたくないものだ。
ではなぜコードをこの様に書く必要があるのだろうか?
A1レベルのScala開発者は、なぜそうするか、何をしているか理解していないA3/L3レベルのコーダーよりもメンテしやすいコードを書くだろう。
10. Call out ugly code
馬鹿げたほど見にくいScalaを書くことはできる。
でもそれは馬鹿げたほど見にくいJava、Perl、英語を書けるのとおんなじことだ。
ただ一つだけJavaとScalaで大きな違いがある。
Scalaは様々な方法で醜くなることができる。
見にくい命令型Scala、見にくい関数型Scala、またはそれの両方。
なれてないせいでよくわかっていない書き方をしてるせいだ。
Scalaは新しい言語だからJavaのように特定のアンチパターンのようなものはまだ確立していない。
そのせいで醜いものが美しく見えたり、その逆が生じることもあるかもしれない。
学ぶにつれ醜いパターンを削除していくかもしれないが、それが将来より醜いコードを生み出すかもしれない。
このように犠牲に基づいたフィードバックのループは始まる。
素晴らしい開発者が醜いScalaを書いているときは思い切って聞いてみよう。
質問するのだ。
Scala初心者だからといって何も役に立てないと思うのは間違っている。
最も避けたい最悪のシナリオは仮定が間違っていて、あなたのほうが美しいコードを思いついていて、あとになってそれを悟ることだ。
11. Scala is only one part of the puzzle
10年前と比べてアプリケーションの開発環境は様変わりした。
私は今Scala、Play、AngularJS、それにMongoDBを使用したアプリケーションを作っている。
殆どはクライアントサイドの仕事だ。
この一年ScalaよりもAngularを書いて過ごした。
別に悪いことではない、現実がただそうであるというだけだ。
JavaなどのボイラープレートやRubyのような動的言語の脆さにさらされることなく、クリーンで堅牢なサーバーサイドコードを書けることがScalaの美しさだ。
Scalaを書きながら得たサーバーサイドのロジックを流用してクライアントサイドのコードを自信を持って書くことができる。
そうして銃弾さえ防ぎ、同時に母親の腕の中のゆりかごの様に柔軟なコードを書くことができる。
Scalaのグランドマスターであろうとすると同時に、私は広く様々な技術の先端にいたいという思いがある。
HTML5、SASS、AngularrJS、RequireJS、SQL、MongoDBなどなどなどなど。。。
一つの言語のあらゆる側面をマスターする時間がないとしても、Scalaは飛び込んで学ぶ価値のあるテクノロジーだ。
リアクティブプログラミングは次の10年のデファクトスタイルになるだろうし、Scalaがそのパラダイムシフトの最前線にいることになるだろう。
パフォーマンスとスケーラビリティは無視できないレアクティブアプリケーションのメリットだ。
全国でJsonはXMLを代替しているし、RESTは複雑なSOAを駆逐している。
デスクトップアプリケーションはモバイルに取って代わられている。
莫大な量のデータをなにか意味のある知識に変換する処理は、Akkaによってハードウェアをアホみたいな量増やさなくても達成できる。
Scalaはパズルの一部分でしか無いが、新しいアプリケーションを生み出すためのコアなピースとなるだろう。
12. Learning Scala will make you a better programmer
企業勤めのエンジニアが本当に成長を求められることはあまりない。
最後にソフトウェア開発に対して全くもって違うアプローチを学ぶ必要があったのはいつだろう?
最後の大きなシフト、それにキャリアで経験したただ一つの大きなシフトだが、それは手続き型言語からオブジェクト指向言語へのシフトだった。
1998年にカナダの銀行であるCIBCで初期のJavaアプリケーションを開発できたのはラッキーだった。
一緒に働いていたCOBOLやCのエンジニアは信条を大きく変える必要があった。
今日ではJavaは大きな支持を得ているが、それは当時JavaはWindowsやOS/2の大量のクライアントに向けてデプロイするとき非常に実践的だったからだ。
実際にパンチカードでプログラミングしていたような20、30年の経験があるエンジニアと働いた経験からは大きな学びを得た。
一つのプログラミングスタイルに固執してはいけないという学びだ。
Javaを学んだ時同時にJCLもメンテしなければならず、昔のCOBOLやFusion 360アセンブリコードを学ぶ必要があった。
いろんな観点で物事を見る必要があった。
JCLやCOBOLは魅力的ではなかったが、それでもやるべきことはやっていた。
CIBCでインターンしていたときにSmalltalkからExcelまですべての事を調査する必要があった。
Excelで関数型プログラミングを初めて学んだのだ。
Scalaは不当な評価を受けることがよくある。
成長もせずに、Scalaについて悪態をついて他のよく知られた言語に逃げる人がいるのだ。
別にそれはいい。
問題は後々まで残る悪評、非推奨の言をオンライン上に残すことだ。
これはScalaにとってはフェアじゃない。
興味を持ってくれた人に言語の価値に疑問を抱かせてしまう。
Scalaを非推奨するものを読んだら誰が書いたかを知るべきだ。
必要とする要件がそもそも違う可能性がある。
簡単に人の意見に左右されないことだ。
チャレンジングなことは誰かの拒否反応を起こすことはままある。
Scalaの成功体験を探してみることだ。
それは普通に見つかる様になっていくだろう。
Conclusion
Scalaは単なる技術的な投資ではなく、カルチャーに対する投資でもある。
得られるものは大きいし、どうせなんらかの方法でそれはやらなければならない。
もしスケーラビリティと信頼性、メンテナンス性が必要な新しいプロジェクトで開発している、もしくはプログラマとして成長したいならScalaはまさしくそれに見合ったものになるだろう。
普通に考えてもそんなに難しい移行でも無い。
最後に、Scalaはエンタープライズでの運用に耐えうるものだし、既に運用されている。
さあ始めてみよう!