こんにちは、バックエンドエンジニアのKazです。
PHPとGoって何が違うの?LIGが自社サービス開発にGo言語を採用したお話
前回の記事「PHPとGoって何が違うの?LIGが自社サービス開発にGo言語を採用したお話」では、LIGが開発言語をPHPからGo言語に乗り換えてみて感じたメリットをご紹介いたしました。
しかし言語を乗り換えることによって、さまざまなリスクも生じます。甘く見るとあとで大きな負担となってのしかかってくることも……。
この記事では、GO言語に乗り換えることでどんなリスクがあるのか、また実際にどのようにそれを評価・解決したのかを紹介していきます。
PHPからGoへの乗り換えるリスクは?
前回の記事で紹介したように、PHPとGo言語ではその中身に大きな違いがあります。言語仕様はもちろん大きく異なりますし、比較で挙げたコンパイラ言語とインタープリタ言語、静的型付けと動的型付けという根本的な動作方式さえも違えば、その使いこなしかたに関する考え方もおそらく大きく異なります。
具体的には、既存のソースコードはもちろんそのままでは使い回すことができませんし、いままで雑なロジックでもそれなりに動いていたコードの書き方さえもきちんと再設計しないと実運用に耐えないものになってしまうことさえあります。
こうなると一言に「言語の乗り換え」といえど、さまざまなリスクが気になってきます。
- 新しい言語を習得するための「学習コスト」
- コードを移植し、データやリソースを再利用するための「移行コスト」
- 開発難易度の違いによる開発スピードの差から発生する「開発コスト」
- 新しい言語に対応したエンジニアを採用しつづけるための「維持コスト」
もちろん先に述べたように移行にはさまざまなメリットもありますので、ここではまずメリットを念頭に入れた上で各リスクを一つ一つ検討していきます。
学習コストを抑えるポイント
PHPとGo言語に限らず、言語の乗り換えには多大な学習コストがかかりがちです。いままで使っていた実行環境も、便利に使いこなしていたライブラリやフレームワークも、場合によっては一部のビルトイン関数さえも新しい言語には存在しません。これらは全て改めて調べなおし、使い方を学習していく必要があります。
もちろんこれまでに培った知識や経験がまったく無駄になるわけではなく、コンピューター言語全般におよぶ基礎的な知識、ロジックや設計に関する考え方は全て共通なので、第二言語は比較的スムーズに学習することができます。
従ってここでかかってくる学習コストとは、
- 言語の特性の違いの理解
- 新しい言語に含まれるビルトイン関数や新しく使うフレームワークなどの調査
などであり、あとはひたすら慣れる作業になります。
この調査や仕様の理解に必要なのは「ドキュメントやWeb上のナレッジの充実度」です。新しい言語に移行する場合は、これらの情報がいかに整っているかが学習コストに直結してきます。
ドキュメントは充実しているか?
ドキュメントと一口に言っても、ライブラリの使い方を詳細に解説したものからサンプルコードを羅列したもの、各関数のリファレンスまでその種類は多岐に渡ります。
もちろん前者2つも重要なのですが、新しい言語やフレームワークを導入する上で地味に無視できないのが、関数リファレンスなどコードレベルのドキュメントです。これはいざ踏み込んだ作業をおこなおうとしたとき、詳細な挙動を理解しようとした際に欠かせない存在となります。
PHPをはじめ多くの言語では、コードレベルでのドキュメントの公式フォーマットがありません。たとえばソースコード上に好き勝手な形式で各関数の挙動の説明や実装の理由が書かれていたり、さまざまなフォーマットで独自の形のドキュメントを残していたりと、使用するライブラリやフレームワークによってバラバラのドキュメントを参照する必要がありました。
このため近年ではJavadocやPHPdocなど、ソースコード上に統一された形式のコメントを残し、ツールを使って自動でドキュメントを生成する手法が広くおこなわれるようになってきています。
しかしながらこの手法も言語として統一されたフォーマットではないため、未だに勝手記法のコメントやドキュメントが残されたライブラリは多数存在しますし、そもそもコメントを残すことが必須ではないため億劫なプログラマーはコメントを省略しがちになってしまうなど完璧な方法ではありません。
Godoc:統一された公式のドキュメント形式
その点、Go言語では公式で「Godoc」というコメントの統一フォーマットが用意されていて、すべてのパッケージのドキュメントを自動生成してHTTPサーバーまで起動してくれるgo doc
コマンドが標準で含まれるようになっています。
この統一フォーマットのおかげで、あらゆるパブリックなパッケージのドキュメントを自動生成してホストする「GoDoc」というサービスも公開されており、このサイトではGitHub、BitBucket、LaunchpadおよびGoogle Project Hostingでホストされるあらゆるパブリックなパッケージのドキュメントを一元的に検索・閲覧することができるようになっています。
こうして画一的なドキュメントを整備しやすい環境が公式に整えられているおかげで、公式非公式を問わずあらゆるパッケージにコードレベルで詳細に説明されたドキュメントが用意され、ドキュメントの参照にかかるコストをかなり抑えられるようになりました。
仕様を理解しやすいか?
また言語の学習コストを抑える要素として、ドキュメントの充実度に加えて仕様の理解のしやすさも重要です。
いくらドキュメントがそれなりにしっかり書かれていたとしても、たとえばもし関数が思っていた動きと違う挙動をしてしまった場合、プログラマーはその挙動をソースコードを追って原因を突き止めようとします。
より深い階層で挙動を確認しようとするなら、ソースコードを基にしてどれだけ簡単に仕様が理解できるかは開発の難易度に直結してきます。
近年では「慣れたプログラマー」が少ないコード量で作業を実装できるように、さまざまな便利機能が言語仕様に取り入れられていたり、それに倣ってフレームワークにもさまざまな便利すぎる機能が搭載され、一つの関数呼び出しであらゆる挙動をおこなうまるでブラックボックスのような実装さえもはびこっています。
これらは実際それぞれの仕様を完全に理解していればたしかに便利なのですが、実装を知らないプログラマーにとってはコードも追いにくく、挙動を一瞥しただけでは理解できないこともあるなど結果として複雑になってしまっていることが多々あります。
複雑な機構の排除:Go言語をシンプルに保つ設計思想
この点Go言語では学習コストを極力下げるため、複雑な機構はなるべく排除した設計になっています。このためたとえばメソッドや演算子のオーバーロードは「往々にして混乱を招いている」「あれば便利かもしれないが、必須ではないし無いほうがずっとシンプルで分かりやすい」という理由で排除されています。
あくまで私見の範囲ですが、このような思想の言語下で開発されたライブラリやフレームワークも、複雑なコードを書けないがゆえにシンプルでコードを追いやすい実装にされていることが多いように感じます。
もちろん便利機能をすべて排除したわけでは決してなく、無いと困るような機能はどんどん提案と検討がおこなわれていて、シンプルさを担保した上で最適な実装が決まれば導入されるよう機能ごとに議論が重ねられています。たとえばジェネリクス(汎用プログラミング)は今なお継続して導入に向けた議論がおこなわれています。
次回は「言語の移行コスト」について
また新しい言語に移行するにあたって、「既存のソースコードの移植はどうするか」という問題もでてきます。
すでに完成し動いているサービスには今まで「投資」してきたソースコードという資産があり、新しい言語に移行するとこれらを原則として書き直す必要がでてきます。
この解決策をどうするのか、次回の記事では引き続き「移行コスト」についてどのような問題があるのか、またLIGがいかにこれを回避したかをご紹介していきます!
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。