Deno(v1.25.0)でMake a Lispした
過去2回ぐらい挫折していたMake a Lispをカンニングも辞さない勢いでやりきった。
実装するLisp方言は、Clojureっぽい構文を採用したMalというもの。
リポジトリはこれ。最近会社でやたらとTypeScriptを触っているので & 流行っているらしいので、Denoを使用した。
Deno自体の感想は浅い使い方しかしてないので、「七面倒くさいtsconfigとか書かなくてええな」というかんじ。
Step 0: The REPL
空っぽのインターフェイスを書くだけ。終わり。
Step 1: Read and Print
字句解析と構文解析。一番カンニングした章だった。
Step 2: Eval
抽象構文木を深さ優先でひたすらevaる。
ここから先はガイドを読んどけば詰まることはない(かもしれない)。
Step 3: Environments
例のごとく変数と値のセットを記録するデータ構造を作る。
あとついでに特殊形式のdef!
, let*
を導入。
Step 4: If Fn Do
特殊形式を追加。とくに言う事なし。
Step 5: Tail call optimization
末尾再帰最適化。適当に再帰しとけばよかったので単純かつ美しかったおれたちのeval
関数が、無惨な姿となる。
あと普通に難しい。
Step 6: Files, Mutation, and Evil
一般Lispのatom
とClojureのatom
がまったく別の概念だということがわかる章。
ここまでデフォルトイミュータブルだったが、参照経由で値を再代入することが可能となる。
Step 7: Quoting
quote
とquasiquote
。はちゃめちゃにむずい。
わかりやすい解説はお気楽xx入門の人のページとかかなあ。
Step 8: Macros
Lispのマクロって構文木をコードからいじれるって程度の理解だったが、
In this step you will be able to mark mal functions as macros which can manipulate mal code before it is evaluated. In other words, macros are user-defined special forms.
って説明でしっくりきた。
Step 9: Try
いがいと実装がむずい。
Step A: Metadata, Self-hosting and Interop
セルフホスティング。
エラーメッセージが想定と微妙に違ったりファイルパスを修正するのがめんどいので、この章はあまり真面目にやっていない。
雑な感想
- なんとなくわかってはいたが、代数的データ型 & パターンマッチのない言語で言語処理系つくるのはマゾ行為ということを確信した。
vector
型いる?conj
で違う動作をすることくらいしかlist
型との差異がなかったような。meta-data
ってなんじゃこりゃ。あほのおれには使い所がさっぱりわからん。Next StepsにErrors with line numbers and/or stack traces.
とかあるから、それで使うとか?