ビールをおごる🍻

okuzawatsの日記

モバイルアプリケーション開発の沼💀

「Go言語でつくるインタプリタ」を読みました📚

書いている人

モバイルアプリケーションアーキテクトとして働いています。モバイルアプリケーションのアーキテクチャ、自動テスト、CI/CDに興味があります。


Go言語でつくるインタプリタ」 (Thorsten (2018))を読みました。読みました、というか読んでインタープリタを実装し、一部の構文を追加で実装しました。書籍を購入したのが2022年5月、そこから一度チャレンジして諦め、2回目のチャレンジが2023年1月、3回目のチャレンジで読了できました。足掛け2年5ヶ月となかなか時間がかかり、途中しんどい時期もありましたが、読了できて良かったです。

ソースコードはこちらのリポジトリに置いておきました。GitHub Actionsで実装したインタープリタを実行して、FizzBuzzを動かすところまで書いてあります。

インタープリタに関する学習の履歴

2022年5月にインタープリタを実装して学ぼうと思い立ち、最初に手に取ったのが本書「Go言語でつくるインタプリタ」でした(たぶん)。飽きたのか挫折したのか(おそらく後者)、最初のチャレンジは失敗に終わりました。

その後、「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」 (遠藤 (2017))という書籍に出会い、「Go言語でつくるインタプリタ」に再チャレンジする前に、こちらの本を先に読みました。

「RubyでつくるRuby」は、「Go言語でつくるインタプリタ」よりも入門的な書籍です。「Go言語でつくるインタプリタ」では構文解析のところから実装していきますが、「RubyでつくるRuby」では著者の実装したライブラリを利用することで構文解析の実装とその説明を省略し、読者は抽象構文木の評価のみを実装します。「RubyでつくるRuby」を読了すれば、Ruby(のサブセット)のインタープリタが完成します1

「RubyでつくるRuby」を先に読んでおいて良かったと思ったことが一つあります。「Go言語でつくるインタプリタ」では構文解析の実装が終わらなければ動かすことのできない、実際にインタープリタを動かしてプログラムを実行する、というところを先にできたことです。実際、「Go言語でつくるインタプリタ」の後半の内容は、「RubyでつくるRuby」で学習済みの内容が多く、既視感を感じながら実装することになりました。

ゴールが見えていることで、「先の見えなさ」からくるモチベーションの低下がなくなりました。

何故、2回も「Go言語でつくるインタプリタ」のチャレンジに失敗したのか

内容を十分に理解できなかったこともありますが、同じような実装が続いて飽きてしまうためです。今回の3回目のチャレンジでも、飽きとの戦いがありました。しかし、前よりもインタープリタの理論を理解できてきたこと、Go言語についても理解を深めたことで、何とか読了することができました。

インタープリタを拡張した

FizzBuzzを実装するために剰余演算子が欲しかったので、インタープリタを拡張して剰余演算子を実装しました。20分くらいで実装できて感動しました。

最終的に、こんな感じでFizzBuzzを実装しました。

let fb = fn(n) {
  if (n > 1) {
    fb(n - 1);
  };

  if (n % 15 == 0) {
    puts("FizzBuzz");
    return;
  }
  if (n % 3 == 0) {
    puts("Fuzz");
    return;
  }
  if (n % 5 == 0) {
    puts("Buzz");
    return;
  }
  puts(n);
};

fb(100);

まとめ

読んでいる途中は「楽しい」という感覚はあまりありませんでしたが、いざ完成して自分で書いたプログラムを動かせるようになるととても楽しいです!また、言語処理型の気持ちがすこしだけわかるようになった気がします🤏

Reference

  1. Thorsten Ball, 設樂洋爾(訳), (2018), Go言語でつくるインタプリタ, オライリーオライリージャパン
  2. 遠藤侑介, (2017), RubyでつくるRuby ゼロから学びなおすプログラミング言語入門, ラムダノート
  3. okuzawats/writing-an-interpreter-in-go(最終アクセス日:2024年10月27日)
  4. okuzawats/minruby-interpreter(最終アクセス日:2024年10月27日)

  1. 関数の評価のところが、どうしても正しく実装できませんでした。全体を何度も見直して、エラッタも読みましたが…。もう1回、「RubyでつくるRuby」にもチャレンジしてみようかなと思っています。 ↩︎

Related