F#で『アンダースタンディング コンピュテーション』をやる

リポジトリはこれ。

https://github.com/guricerin/understanding-computation

公式ページ : https://www.oreilly.co.jp/books/9784873116976/

Rubyでオートマトンだの言語処理系だのを実装しながらCSを浅く広く学ぶ本。本に載ってるサンプルコードを例によってF#に翻訳した。
実は去年の時点で既にF#で実装していたが、パーサーなど色々と未実装なものが多かった。今回はFParsecを使うことで構文解析の部分も完成させることができたので、こういった分野にも少しづつ慣れてきたかもしれない。

Rubyでの写経、去年のF#への翻訳、そして今回と、計3回もこの本を読んできたわけであるが、相変わらず完全に理解したとは言い難い。自分は学習障害なんじゃないかと本気で疑っている。

本書の解説は他にやってるブログが大量にあるし、そもそも本書を読めばいいのでやらないが、ここでは「動的型付け言語で実装したほうが良い」という本書の警告(明示的にそう書いているわけではないが)を無視して静的型付け言語をチョイスした場合に挫けやすいであろう部分を列挙しようと思う。

型合わせパズル

例えばint型のデータを想定して実装していたら、十数ページ後に気軽にObject.newnilをぶちかましてくれる。
また他には、Set<‘a>だと思っていたデータが実はSet<Set<'a>>でしたなど、なんどもコードを修正していると発狂しかける。
まあ型推論に導かれて助けられる部分もあるので、他の辛い箇所よりはましかもしれない。型推論のない言語?…がんばってくれ。

第6章

一部界隈では有名な、ラムダ式だけで実装する例のトチ狂ったFizzBuzzが解説される章である。静的型付け言語ではかなり苦しい、というか無理。
とはいえC++やRustなどメタプログラミング機能が充実した言語なら、気合でなんとかなりそうではある。参考までに、Rustに翻訳した他の人のリポジトリを貼っておく。

https://github.com/yodalee/computationbook-rust

一応、F#にもFSharp.Quotationsというメタプログラミング用のライブラリはあるのだが、これがかなり保守的な作りでC++みたいにやりたい放題なコードを生成できるわけではないっぽい。あるいは単におれのF#力が低いだけかもしれないが。
おれのコードではチャーチ数でゴニョゴニョしてお茶を濁している。

第8章

自己参照プログラムやevalなど、Rubyの本領が発揮される章である。おれが書いたF#コードでは最小限の実装で留まってしまっている。
FSharp.Quotationsが活躍しそうな雰囲気を醸し出しているが、やはり先述の理由で諦めた。

他にもあったかもしれないが、このへんで撤収。