プログラミング言語の面白さを教えてくれた本

この記事は「買ってよかった技術書を紹介しよう！」イベントの参加記事です。

https://qiita.com/official-events/8746fa99d4e403fad3d1

# はじめに

プログラミング言語―コーディング時は空気のようでいながら、中には数学、言語学、高速化技術が詰まっています。作者の思いも詰まっています。

ソフトウェア開発に興味を持ったのはプログラミング言語に惹かれたのがきっかけでした。
小さいながら自作のプログラミング言語も作ったりしています。

https://qiita.com/Syuparn/items/87cafc7fd206016a0f8d

本記事では、プログラミング言語の理解、作成にあたり影響を受けた本、心に残った本を紹介します。

# 言語のしくみ

Rubyの作者Matzさんが、Streem言語の開発を通じてプログラミング言語の作り方を解説された本です。
この本が自作言語を作ってみるきっかけになりました。

https://www.amazon.co.jp/dp/B01N7JZXMD

https://github.com/matz/streem

言語開発を時系列で記載しているスタイルなので、作っていく上での試行錯誤、決めの問題をどう対処していくのかを追体験できます。

特に、「便利そうに見える文法が別の文法と衝突したのでやむなく修正した」というエピソードが度々出てくるのが印象的でした。言語の文法は与えられたものではなく、いろいろな希望、理想の折衷案でできていくという見方を学びました。

# 言語設計者たちが考えること

18個のプログラミング言語それぞれの作者にインタビューし、言語の生い立ち、設計思想、こだわりポイント、展望等を対談形式で記載した本です。 ~~古い本なのでお値段が... :sob:~~

https://www.amazon.co.jp/dp/4873114713

言語で重視している点、「使いやすさ」の軸が様々なのが面白かったです（書きやすさ、シンプルさ、安全性、省メモリetc...）。

一方、言語づくりの大半は「平凡な機能の実装」という言葉が印象に残りました。

> 人々が新しいプログラミング言語を作る時によく犯す間違いは、解決しようとしている特定のひとつの問題に夢中になってしまうことです。...あらゆるプログラミング言語は、10%の新しい部分と90%の平凡な部分から構成されているのです。新しいプログラミング言語に見受けられる、これら多くの革新的ソリューションは10%の新しい部分にあり、彼らは素晴らしい仕事を行っているかもしれません。しかし、残りの90%はどの言語でもプログラムを書けるようになるためにやらなくてはならないものであり、その部分における彼らの仕事の出来は良くないのです。だから失敗するのです。
> 
> 「言語設計者たちが考えること」 P.323 アンダース・ヘルスバーグ

どうしても言語の独自機能に目が行きがちですが、それは地味だけど大切な基礎があってこそのだと痛感しました。

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

1冊かけて、動的型付き言語Monkeyを1から作る方法を紹介しています。

言語の構成要素、Lexer, Parser, AST, Object, Evaluatorを一通り実装できます。さらにTDDも身につく。読了に1か月弱かかりますが、読むだけでなく写経することをおすすめします。

拙作のプログラミング言語もGo製で、Monkeyの構成を ~~パク~~ 参考にしています [^monkey]。

続編に「Writing A Compiler In Go」（未邦訳）もあるので、こちらもいつか挑戦したいです。

https://www.amazon.co.jp/dp/B07FZWWVQT

# プログラミング言語大全

なでしこの作者クジラ飛行机さんによる、プログラミング言語の図鑑です。

https://www.amazon.co.jp/dp/B088NFBXTY

各言語1~4ページで特徴や文法の比較(FizzBuzzのサンプルコード)が解説されています。イラストも多く手軽に読めます。
このリストにある言語を「死ぬまでに書きたい言語リスト」として、毎年1つずつ触るのが目標です[^lang]。

# ハッカーと画家

Lisperでありハッカーであるポール・グレアムさんのエッセイ集です。（プログラミング言語以外の話もあります）

https://www.amazon.co.jp/dp/4274065979

（無料でも公開されています）

http://practical-scheme.net/trans/hundred-j.html

「百年の言語」では、高速化のためのテクニックが一切不要になった100年後の言語を思考実験しています。今よりずっと高速なので、「intのプリミティブは不要（リストの長さで表現する！）」「並行処理はコンパイラ内部に隠蔽される」etc... そして、言語は今より書きやすさを重視した形式に進化するという内容です。
本章を読んで、「おきまりの構文」が実は計算速度のための慣習にすぎなかったのかと気づきました。新しい言語を作る際には、大胆な発想を持ちたいです。

# 7つの言語、7つの世界

「パラダイムの違う7つの言語を学び、言語に対する引き出しを増やそう」という狙いの本です。

https://www.amazon.co.jp/dp/4274068579

原題は「Seven Languages in Seven Weeks」で、各言語3日*7週間で言語の特色を知れます。練習問題もあるので、実際に機能を理解できているかの腕試しもできます。
一冊で7言語学べる。なんてお得な本！[^7lang]

扱う言語は以下の7つです。

- Ruby: クラスベースOOP
- Io: インスタンスベースOOP
- Prolog: 論理型
- Scala: 関数型/クラスベースOOP
- Erlang: 関数型
- Clojure: 関数型
- Haskell: 関数型

パラダイムの他、動的/静的型付き、コンパイラ型/インタープリタ型等の区分でも多様な顔ぶれとなっています。

# このプログラミング言語がすごい！

8つのマイナー言語を紹介している同人誌です。（技術書典の期間中しか買えない？）

https://techbookfest.org/product/5180136513077248

解説書も記事も少ない言語をオムニバス形式で紹介していて、特徴的な一面を知ることができます。（「[E言語](http://www.erights.org/elang/index.html)」は本書がなければ一生出会わなかったと思います...感謝 :pray:）

扱う言語は以下の8つです。

- Dart
- E
- Haxe
- Lazy K
- Nim
- Q#
- V
- Web Ontology Language

# メタプログラミングRuby

メタプログラミングを使って、コードの重複を排除し簡潔にする方法を紹介している本です。

https://www.amazon.co.jp/dp/4873117437

メタプログラミングの技術自体も興味深いですが、その背後にある仕組みを通じてRubyの動作原理、OOPの考え方を深く知ることができます。
特に、特異クラスを使ったクラスメソッド実現の仕組みに感動しました[^meta]。すべてのオブジェクトを自身の特異クラスのインスタンスとすることで、クラスメソッドとインスタンスメソッドの仕組みを同一視する...シンプルだけど強力な機構に美しさを感じました。

# あなたの知らない超絶技巧プログラミングの世界

再びRuby[^chouzetsu]。自分自身を出力するコード(Quine)や記号だけのコード等、美術品のような不思議なコードを紹介した本です。

https://www.amazon.co.jp/dp/B015R0GNXK

「超絶技巧プログラミング」の作り方の解説もあり、文法の可能性の限界に挑みます。実用性ありきではなく、純粋に言語を味わうことができました。
難しくてまだ理解できていない箇所もありますが、写真集のように見ているだけでも楽しい本です。

（触発されて自分でも作ってみました。記号だけのPythonコード）

https://qiita.com/Syuparn/items/1afa97e8dd731923f1ad

# Land of Lisp

Common Lispの入門書。ゲームを作りながら言語仕様が学べる本です。楽しい。

https://www.amazon.co.jp/dp/4873115876

本書に、そしてLispに触れることで、AST(抽象構文木)を身近に感じるようになりました。

プログラミング言語を評価するには、構文を解析し、ASTにしてから評価する。ユーザーが構文を弄りたいなら、ASTを編集する必要があるが、機能を提供するのもユーザーが使うのも少し大変。...では、もしはじめからASTでプログラミング言語を作れたら？

Lispです！LispはASTとソースコードが同一視(S式)できるから、ユーザーが手軽に構文を追加できる（quoteでマクロ作成=AST変換）ということを実感しました。
loopだけで構文が数十種類あり、さらにユーザーが拡張できるというのは驚きです。

# おわりに

以上、プログラミング言語好きにおすすめする本の紹介でした。

いざ書き出してみると、ここに書ききれなかった本、逆に定番だけどまだ読んでいない本もかなりありました...型理論やコンパイラの仕組みはあまり触れてないので読んでいきたいと思います。（読んだらまた紹介記事にする予定）

ここまでお読みいただきありがとうございました。

[^monkey]: 実装も参考にしたところはMonkeyのMITライセンスを表記しています。
[^lang]: 「毎年1言語習得する」というのは「達人プログラマー」で提唱された学習方法のようです（が、未読です :pray: ）
[^7lang]: もちろん構文の網羅的な説明までは書かれていないので、実務で使う場合には別途その言語の入門書もあったほうが良いでしょう。
[^chouzetsu]: Ruby以外のコード例もあります。
[^meta]: そして、「RubyはインスタンスベースOOPの考え方も取り入れている」という説明の意味が分かりました。