NOTE: 利用參考等價性質的技巧
1. 說明
所謂的使用參考等價性呢,是指在某些語言裡面,兩個物件是否相同是通過參考而非內容決定的。 舉例來說, racket 裡寫下一個空結構,然後生成一些實例
(struct id ()) (define a (id)) (define b (id)) (define c a)
我們可以用一些 eq?
運算來檢查
> (eq? a b) #f > (eq? a c) #t > (eq? c a) #t > (eq? b c) #f
這樣就可以生成一連串在運行中的程式內唯一的資源標示。
但要小心你用的語言的特性,比如要是我把上面的
(struct id ())
變成(struct id () #:transparent)
並改用equal?
運算, racket 就會改用內容而非參考去判定相等。
2. 實際例子
那麼這種技巧可以用在哪些地方呢?首先要注意到這絕對不可以用在序列化上!每次程式重新啟動,同一個宣告都會被重新分配到不同的參考,所以這不能超出程式運行的範疇。 所以合適的用法應該是在程式終止之後就不會再仰賴這個資源唯一性的。
2.1. Racket 自己的 Sets of Scopes
在 Matthew Flatt 的 Let's Build a Hygienic Macro Expander 裡,=scope= 就是一個空結構。
2.2. Type checker 中的自由變數
型別檢查裡面的自由變數也可以用這個方式生成(這樣我們就不用維護一個 free variables counter)。
2.3. threading ID
共時結構要是需要唯一標示的時候,這個技巧就很方便,因為沒有正確運作的記憶體配置器會把物件分配到同一個地方。
3. 結論
這樣的小技巧非常方便,當然也需要注意其限制以及程式語言的實際運作方式。 在使用前最好真的去讀你的語言對參考的處理方式,確保這些程式仰賴的環境假設正確無誤,才不會出現出乎意料的問題。