「Go言語らしさ」とは何か? Simplicityの哲学を理解し、Go Wayに沿った開発を進めることの良さ

プログラミング言語には作者の設計思想が強く現れますが、Go言語もまた後発であることを生かし、しっかりとした思想に基づいて開発されています。公式のドキュメント等で語られているSimplicityの哲学を理解し、Go言語らしさ、Go Wayに従って開発する良さについて、はてなチーフエンジニアの松木雅幸(Songmu)さんが解説します。

「Go言語らしさ」とは何か? Simplicityの哲学を理解し、Go Wayに沿った開発を進めることの良さ

1id:Songmuと申します。はてな東京オフィスでチーフエンジニアを務め、Mackerelというサーバー監視のSaaS開発においてプロダクトマネージャーを担当しています。

筆者が勤めている株式会社はてなでは、2013年よりGo言語を開発に用いるようになりました。導入当初はMackerelで用いられる監視エージェントであるmackerel-agentから始まり、現在ではURL外形監視のためのサブシステムや、時系列データベースのミドルウェア、最近では新規プロジェクトでの採用など利用シーンが多岐にわたっています。

筆者はJavaの経験は少しありましたが、Perlなどの動的型付けのスクリプト言語での開発が長く、最初はGoに慣れない点もありました。しかし、今では大好きな言語のひとつになり、筆者のGitHubでは、Goのツールやライブラリを数多く公開しています。

今回、「Go言語らしさ」をテーマに記事を執筆してほしいという連絡が来たときは、「これは大変な依頼が来てしまったな」と思いました。そのテーマで記事を書くにはよりふさわしい方がいるようにも思いましたし、Goは後発のプログラミング言語でもある分、設計思想がしっかりしており、それらの多くは既に作者や開発者チームによって語られているからです。

プログラミング言語はその作者がしばしば「優しい終身の独裁者」などと称されることがあるように、特に作者の設計思想が強く現れるソフトウェアです。Goの場合でも、初期開発者のRobert Griesemer、Rob Pike、Ken Thompsonの3名や、コア開発者のRuss Coxにより、Go Blogや彼らのプレゼン資料、ブログなどでその背景や設計思想が綴られています。

2

Go Blogで2018年4月26日に発表された「Go's New Brand」にもGo言語の設計思想が反映されている

本稿では、Go言語の作られた背景・設計思想に改めてふれるとともに、筆者が考える「Go言語らしさ」や、Goらしいコードを書くために心掛けていることをお伝えします。

Go言語らしさとは

Go言語が業界に急速に受け入れられている大きな理由に、「そもそもの思想の筋の良さ」と「現代のニーズにマッチした言語機能」があると筆者は考えます。

つまり、過去に正しく学び現代の開発に必要な機能を盛り込み、加えてこれからの未来に求められるフィーチャーを提案し実現しようとしているという、過去・現在・未来がバランスよく考慮された優れた設計になっているのです。

言語設計の経緯や、現在の潮流の中で言語に求められている機能を把握すると、一見特殊にも思えるGoの言語機能がなぜそのようになっているのか、どういった言語特性が世の中に受け入れられているのかを理解することができ、より「Goらしい」コードを書けるようになるでしょう。

Goが作られた背景

Goが作られた背景としては、Rob Pikeによるドキュメント「Go at Google」を読むと、Google社内における大規模ソフトウェア開発の生産性やスケーラビリティのためだということが分かります。

The goals of the Go project were to eliminate the slowness and clumsiness of software development at Google, and thereby to make the process more productive and scalable. The language was designed by and for people who write―and read and debug and maintain―large software systems.

Go's purpose is therefore not to do research into programming language design; it is to improve the working environment for its designers and their coworkers. Go is more about software engineering than programming language research. Or to rephrase, it is about language design in the service of software engineering.

引用:Go at Google: Language Design in the Service of Software Engineering 3. Go at Google

筆者が特にGoに対して好ましく思っている点は、ここに書かれているように、Goがプログラミング言語研究のための言語ではなく、実際の問題解決のための言語だということです。その点は、プログラミング言語そのものが好きな人にとって物足りなく感じられる部分ではあるのでしょう。

また、上記の「Go at Google」のほかにも、公式のFAQには開発のコンセプトや思想が事細かに書かれています。それぞれの記事では、Goが作られた背景には以下のような課題があることが述べられています。

  • プログラミング言語そのものが開発されている環境と、実際に使われている環境が異なる
  • ソフトウェアを開発する速度にもスケーラビリティが求められている
  • 既存の静的言語の多くはパッケージの依存管理が大変である
  • GCと並列計算の両方が、一般的な言語ではうまくサポートされていない
  • マルチコアネイティブな言語が求められている

また、これらを踏まえ、FAQの中の「何故新しい言語を作っているのか」という項目では以下のように述べられています。

Go is an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language. It also aims to be modern, with support for networked and multicore computing.

引用:Frequently Asked Questions (FAQ) - The Go Programming Language

Goは、動的型付けのスクリプト言語における開発の効率性と容易さと、静的型付けの言語の安全性を融合させる試みであり、ネットワークやマルチコアネイティブなモダンな言語であることを目標にしていることが分かります。

実際に筆者は、Perlのようなスクリプト言語での開発経験が長いのですが、Goにはすぐ馴染(なじ)むことができました。スクリプト言語の感覚で開発できる静的型付け言語であるように感じています。

例えば、スクリプト言語での開発の場合、少しずつ開発コードとテストコードを交互に書いて動作を細かく確認しながらインクリメンタルに開発を行いますが、Goでもそのリズムを大きく変えることなく開発が可能です。Goのコンパイルが速くテストも書きやすい点が大きく寄与していると感じます。

Goを作った人たち

Goは、Robert Griesemer、Rob Pike、Ken Thompsonの3名によって開発が始められました。

Rob PikeとKen Thompsonの2人は、計算機の世界では神様と言っていい存在です。Ken Thompsonは、C言語やUNIX、UTF-8のオリジナル開発者の一人です。Rob PikeもUNIX開発に携わり、UTF-8の初期設計を行ったことで知られています。

そんな彼らが設計した言語ですから、過去の言語設計で失敗した反省が、Goには活かされているようにも感じます。例えば、以下のような点が挙げられるでしょう。

  • 変数の型宣言が後置である
  • switch文で、デフォルト挙動でbreakする
  • 外部パッケージの読み込みが、マクロではなく構文として用意されている
  • 暗黙の数値変換を提供していない
  • 関数の返り値を複数持つことができる

ScaleとSimplicity

Goのゴールは、2種類のScale ―システムのスケーラビリティと開発のスケーラビリティ― であると、Russ Coxは「Toward Go 2」という記事で述べています。

この2つを実現する上で大事なキーワードが、Simplicityです。Goの言語としての優位性は、シンプルなものを組み合わせたバランスの良さにあります。

多くの言語が同じような機能追加競争を行うと、ともすればそれぞれが似通った言語になりかねません。一方、Goは機能を削ることで勝負しています。コア開発者の全員が必要だと思った機能しか言語に取り込まないという方針が、言語の仕様をミニマムに保つ上で非常にワークしていると言えます。

キーワードが25個しかないミニマルな文法や、過剰な表現力を持たせず、素朴さを是とする文化も、こうした思想が反映されているのではないでしょうか。

また、書き手にとっての単純さのために、Go言語が内部で複雑さを隠蔽してくれている機能もあります。それが、GCであり、goroutineとchannelといった並行・並列処理のための機能、そしてインターフェース機能です。

単純ではあるものの強力で奥深いこれらの機能を組み合わせることが、Goプログラミングの醍醐味(だいごみ)といえるでしょう。

Rob Pikeの「Simplicity is Complicated」という資料も参考にしてください。

Goらしいコードを書くことを心掛ける

ここまで、言語を開発した背景や、言語が目指すゴールから「Goらしさ」を概観してきました。ここからは、実際にGoを書く上で、筆者自身が心掛けていることを述べていきたいと思います。

Goに入ってはGo Wayに従う

Goを書く上で大事なことは、まずはGoの作法に素直に従うことです。ほかの言語から来ると、Goのお作法は一見奇妙に感じることもありますが、その違和感をぐっと飲み込んで、素直にGoのやり方に沿ってしばらくコードを書いてみましょう。

自分が慣れている言語のやり方を中途半端に取り込まずに、全面的に従ってみましょう。そうすることで、最初は奇妙に見えた作法が徐々に腑(ふ)に落ちるようになり、Goらしいコードが身に付いてきます。

例えば、簡潔なパッケージ名と短い変数名は、それでも問題ないようにスコープやパッケージの役割を小さく保つためのプラクティスですし、例外のないエラーハンドリングに関しては大域ジャンプや意図せぬクラッシュを排することで特に、並列、並行処理時の見通しを良くするために有用であることが理解できます。

Goらしいコードを書くためのツール群

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