Haskell 實現相關的 reading list
01-29
記錄一下我在開 Haskell 編譯器坑時閱讀過的材料。因為手頭的坑主要是 backend 相關,所以像類型系統等 frontend 相關的材料,就不放上來了。
首先是 GHC 相關的材料:
- Commentary/Compiler - GHC:不了解 GHC 架構的話,自然先從 wiki 看起了,有一些基礎 Haskell 知識就可以。不過看 wiki 時要留心該條目的編輯歷史,比如 Last modified 10 years ago 這種就跟目前的 GHC codebase 不搭邊。
- takenobu-hs/haskell-ghc-illustrated:綜合講述 GHC backend & runtime 的 slide,概括得不錯。
- Making a fast curry: push/enter vs. eval/apply for higher-order languages:關於 STG(Spineless Tagless G-machine)最 up-to-date 的介紹材料,介紹了 STG 的語法、操作語義(基於一個抽象的棧和堆的重寫規則)、實現相關的細節(內存布局等等)。那篇原始的 Implementing lazy functional languages on stock hardware: the Spineless Tagless G-machine 太舊了。
- C--: A Portable Assembly Language that Supports Garbage Collection:關於 C-- 的綜合介紹。C-- 語法類似 C,設計目的是 portable assembler,支持多調用約定、顯式尾調用、垃圾回收等特性。現在的 GHC pipeline 中的 Cmm 就是基於 C-- 的中間表示,所有的 codegen(C/ASM/LLVM)都是從 Cmm 開始翻譯的。雖然這篇比較舊了,不過對 Cmm 不熟悉的話,還是需要讀一下。
- Hoopl: a modular, reusable library for dataflow analysis and transformation:GHC 通過 Hoopl 框架對 Cmm 進行數據流優化,理解 Cmm 相關類型需要參考一下 hoopl 的 paper。
- Low level virtual machine for Glasgow Haskell Compiler:GHC 的 LLVM codegen 實現者的學士論文。將 Cmm 翻譯到 LLVM IR,對於希望做其他 codegen 的項目而言是不錯的參考材料。
- Stack Traces in Haskell:新版的 rts 一個很實用的特性就是 stack traces,所以要移植 rts 的話也需要參考一下。另外對 GHC 的各個 IR 和運行時機制也有簡單的介紹。
- Profiling optimised Haskell - causal analysis and implementation
- Understanding the Stack & Understanding the RealWorld:介紹 Cmm 運行機制的兩個例子。
wiki 和 paper 的局限性也很明顯,因為 GHC 的 codebase 進化實在是太快了,如果項目是基於 GHC HEAD 開發,那麼不時會碰到一些過時的內容,這時最關鍵的參考資料,仍然是 ghc.git 。一些閱讀 GHC 源代碼的小技巧:
- build GHC 時,確保在 configure 之前,首先安裝了 hscolour 工具。默認在 build 完成以後會調用 haddock 生成 ghc 等庫的文檔,如果 hscolour 可用的話,生成的文檔中源代碼部分會帶上彩色的、scope-aware 的超鏈接,閱讀起來非常非常方便,能省掉 n 多的 grep 工作。不過懶得 build 的話可以看我自己 build 的版本:ghc-8.3: The GHC API
- 碰到某個 IR 的類型很複雜,無從下手怎麼辦?可以嘗試將其 abstract syntax 和 concrete syntax 對應起來 —— ghc 提供了各種 -ddump-xx 選項可以將不同 IR 給 dump 到文本文件,在 GHC 源代碼里找到對應的類型,然後在該類型的定義模塊里找到它的 Outputable instance。所有支持 -ddump-xx 選項的 GHC IR 都通過 Outputable class 實現了 pretty-print 的邏輯,所以從該 instance 的定義可以看到 abstract syntax 是如何變成 concrete syntax 的。一部分的 IR 同時提供了 parser,可以在 git repo 里搜索對應的 happy source file,觀察 concrete syntax 如何被解析。
- GHC 的源代碼里有很多有用的注釋,而且會標明 Notes on xxx,這些注釋在 haddock 生成的網頁上不會顯示,但在源代碼頁面里有。這些注釋比任何 wiki 和 paper 都更加 up-to-date。
接下來是 GHC 以外的一些參考材料:
- Towards a Declarative Web:haste-compiler 作者的碩士論文,詳細介紹了 haste-compiler 的架構。haste-compiler 是一個將 STG 翻譯到 JavaScript 的 codegen,支持除 Template Haskell 以外的所有 GHC 語言特性,值得參考。
- Composable scheduler activations for Haskell:介紹了如何將 rts 中涉及並發調度的部分以 Haskell API 的形式提供給用戶自行定製。這項工作最初是在 Haskell 上做的,但是並未在 GHC 上實現,後來一作轉去實現 Multicore OCaml 去了。
- PAEAN: Portable and scalable runtime support for parallel Haskell dialects:提出了面向各種支持並行編程的 Haskell dialect 的運行時框架。
說起來,Haskell 作為一門有 20 余年歷史的語言,獻祭了這麼多 PhD,搞出了這麼多 bleeding-edge 而又不優雅、不正交的特性,編譯器架構也十分龐雜。那我為什麼不像 @Belleve 一樣另起爐灶,開一個優雅的坑,而是想做一個兼容 GHC 的 Haskell 編譯器呢?
推薦閱讀:
※學習haskell的過程中有哪些值得一做的練手項目?
※函數式-21天入門教程
※如何理解F#里的 Computation Expressions (Haskell 里的 Monads? )
※愉悅的scheme之旅(2)--用callcc合成控制流
※R語言函數式編程purrr的應用