Explore cs in depth!

情報系の専門学校生.compiler/assembler/linker/loader/os/any lowlevel implementations

「Go言語でつくるインタプリタ」は前提知識無しで取り組める言語処理系のチュートリアル

目次

概要

※注意

Go言語でつくるインタプリタ

Go言語でつくるインタプリタ

こちらの本を読み終わりました(付録以外)。

言語処理系に興味を持った衝動で買った本ではありましたが、
今まで読んだ本でもトップレベルで完成度の高いものだったので、
ここで紹介しておきたいと思います。

簡単に良いところをまとめておくと、

  • プログラミングの抽象的な概念をより深く学べる
    • これは言語処理系の勉強ならでは
  • TDD(テスト駆動開発)で進行するために開発技術も身につく
  • Golangをホスト言語に選ぶ事で、とにかく可読性の高いコードが書けている

ですかね。

それぞれ詳細は下記に示します。


本題

まずは私がこの本を購入した理由を話した後に、
何故おすすめできるのかについて書いていこうと思います。

私がこの本を購入した理由

それは、

数ある言語処理系の技術書でも恐らく最も初歩的

だったからです。

インタプリタの開発にもいろいろあって、

等、その種類も様々です。

例えばRubyVMベースとしてよく知られていますよね。
そんなRubyは当初Tree-Walking-Interpreterでした。
つい最近はJITコンパイラが実装されていたりと、
どんどん性能が上昇しています。

一般的には、
VM上でバイトコードを実行するタイプはかなり高速に動きますが、
実装自体が難しいですし、前提知識を必要とするでしょう。

私は本当に何も知らない状態から始めたので、
フルスクラッチで開発する本書はとてもマッチしていました

Goの勉強をし始めていたのでコードリーディングで戸惑うことも少なく、
2章から難易度は上がりますが、
単純な実装面ではあまり難しくないのかな?と思わせてくれました。

この本は一貫して言語処理系のとっつきにくさを取っ払おうというスタンスが見受けられます。
省ける所は省き、必要・重要な部分についてはこれでもかと解説する。

そのメリハリが入門者にとってわかりやすい表現となっていることは言うまでもないでしょう。

それから本書は英語で書かれ日本語に翻訳された書籍ですが、
オライリー"翻訳感"に違和感を持つような方でも読みやすいと思います。

砕けた文章で書かれているので、文章を読み解くという部分でつっかかる事はなさそうです。

ページ数も少ないので(写経の量は"控えめに言っても"少なくないけど…)、
書籍学習に慣れていない方でもスラスラ進めそうですね。

ただ上記にもあるようにコード量は中々多いです。
複数ファイルを行ったり来たりするので、
コードリーディング力はそれなりに必要だと思います。


話を戻して、
本書は次のようなプロセスで進んでいきます。

  • 字句解析…どうやってソースコードトークンに分割するか?
  • 構文解析トークン列をMonkey言語の文法にどう当てはめるか?
    • ASTノードの構築・構成の概観
    • Parserの定義・拡張
    • 本格的なテスト駆動開発の実践
  • 評価器の作成…Monkeyの構文をどうやってGo(ホスト言語)と結びつける?
    • 評価器の定義・拡張
    • オブジェクトシステムの理解
    • 数値計算を制御出来るプロトタイプの完成
  • より言語仕様を拡張
    • 文字列リテラル
    • 組み込み関数(ホスト言語で記述された関数)
    • 配列・ハッシュ等のデータ構造

Golangを用いてインタプリタを開発しよう!という趣旨のもと、
プログラミング言語深い理論はそこそこに
実際にどうすれば処理系が作れるのか?というシンプル且つ明瞭な目標に一貫して説明しています。

道中難所というか、理解がスラスラいかないところが何度か出てきます。
そこで振り返ってソースコード全体を概観し、
入力されるMonkey構文とそれに対応するGoの挙動を追い続ければ、
きっと最後まで読み進めることが出来るはず。

Goは現在恐らく最も可読性が高い言語

この書籍の本質は、
インタプリタ開発を通じて言語処理系(コンパイラで言えばフロントエンド)の概念・知識・理論・挙動を紹介したいのであって、
Golangに詳しくなってもらいたいわけじゃないんですよね。当たり前ながら。

なので、これがもしもHaskellで書かれていたら、Rで書かれていたら、
馴染みのない人にはコードを読むのが難しすぎてきっと続かなかったと思います。

しかしGolangコード全体として一定のインタフェースを提供するんですよね。
誰が書いてもGoに慣れていれば大体同じようなコードを書くので、
ネットで調べるとすぐに似たようなコードが上がってきます。

今流行っていて、ユーザもちょくちょく増えています。
かなり人口は多いのではないでしょうか。

そんなGoで書かれているので、もしGoやってないとしても
プログラミングの経験が豊富にあったり、
いわゆるメタスキルを身につけている人であれば難なく読めてしまいそう。


何故オススメ?

プログラミングの本質が見えるから

どんなプログラミング言語でもマシンで実行する以上、
最終的には機械語まで落とし込んでいるわけです。

その手法はそれぞれ異なりますが、
多くの言語に共通しているのは字句解析→構文解析→評価のプロセスを踏んでいるということ。

この流れを実装してみる事で、
言語処理系がどのようにソースコードを解析し、実行しているのかを知ることが出来ますし、
普段自分が使っているプログラムのエラーを見る目も変わってきます。

単純にコード量が多いのでやってて楽しい

プログラミングってちょっとしたコード書くことよりも、
大量のコードがうまく作用しあって一つのアプリ・ソフトウェアを作ることが楽しいものです。

今回は書籍全体を通して一つの成果物 を作るために、
最初から最後まで一つの長い道を歩いている感じがします。

1章で頑張った事が2章で遺憾なく発揮されるし、
4章以前で手間かけて丁寧に設計してきたおかげで4章の仕様拡張を簡単に行えています。

このような比較的規模の大きい開発技術書の中でやるというのは
中々ないので、新鮮でとても楽しかったですね。

テスト駆動開発

テスト駆動開発をめちゃくちゃざっくりいうと、

  • 単体テストを利用する
  • 期待する挙動であれば成功するようなテストケースを用意してテストを書く。
    • この段階では勿論失敗する(RED)
  • テストが成功するように挙動を実装。
    • これをGREEN
  • 最低限テストが成功するようにしただけで最適化されてはいないしコードも読みづらい。

という流れを踏む開発手法のことです。
TDD形式を取るかどうかは別にして、テストを書かないのはナンセンスなわけですが。

この書籍はTDDを取り入れる事で読者にテストケースを適切に定めることの重要性 を紹介できています。素晴らしい。

是非他の書籍も本書のテストコードを参考にすべきです。

読者の為に残された多くの課題

github.com

こちらを見て頂ければわかりますが、
本書はいたるところで

"これは読者にとって良い演習となるだろう"とか、
"これは読者への課題とする。きっと理解が深まるはずだ"みたいな、
所謂「隙」みたいなものを敢えて作っているんですよね。

出来上がるMonkeyインタプリタはめちゃくちゃシンプルでミニマムなので、
如何に読者が拡張するかどうかという面白さが残っているわけです。

私はもう少しMonkeyをいろいろいじって改造してみてから、
自分で言語を作ってみたいなと思っているので、
このスタンスはとてもありがたいですね。


総評

もう一度メリットをまとめます。

  • 言語処理系前提知識一切なし!でもやりたいなら文句なしでこの本
  • コードリーディング力は正直かなり必要。コード量も多いため、基礎体力は必要。
    • Goのおかげで相当読みやすい。

以上の事を踏まえてほしいと思った方が一人でもいれば幸いです。

おまけ

この本のおかげで今までに書けた記事を紹介します。

drumato.hatenablog.com

drumato.hatenablog.com

drumato.hatenablog.com

ここらへんですね。