我一直在測試一些嵌套的宏調用,而他們的工作如預期舉例來說,假設一個虛構添加宏和下面的表達式(...由我預期!):嵌套宏調用安全嗎?
add(1, add(2, 3))
首先在內部添加擴展(2 + 3),其次是外部擴展(1 +(2 + 3))。我已經看到,外部宏不會從內部調用中收到任何噪聲 - 在輸入表達式中 - 所以內部擴展似乎完全透明。這個事實是否永遠成立(即使有更復雜的宏和類型)?這樣做是否安全?
我一直在測試一些嵌套的宏調用,而他們的工作如預期舉例來說,假設一個虛構添加宏和下面的表達式(...由我預期!):嵌套宏調用安全嗎?
add(1, add(2, 3))
首先在內部添加擴展(2 + 3),其次是外部擴展(1 +(2 + 3))。我已經看到,外部宏不會從內部調用中收到任何噪聲 - 在輸入表達式中 - 所以內部擴展似乎完全透明。這個事實是否永遠成立(即使有更復雜的宏和類型)?這樣做是否安全?
最內層的宏總是首先被擴展(即使它們是作爲名稱參數提供的)。
我認爲答案的另一部分是(希望)在擴展內部宏之後,結果在調用外部宏之前進行了類型檢查(否則,輸出可能不會完全鍵入/解析)。 – Blaisorblade
的確,內部宏的擴展在被傳遞給外部宏之前進行了類型檢查。宏擴展在從宏實現返回後總是進行類型檢查。 –
我無法從瀏覽中收集足夠的信息來充分回答您的問題,但您可能對描述Racket宏觀系統的文章感興趣:[一起工作的宏:編譯時綁定,部分擴展和定義上下文] (http://www.cs.utah.edu/plt/publications/jfp12-draft-fcdf.pdf) –
我不太清楚具體的論文,我只讀過會議版本,但斯卡拉的宏觀系統是並不完全可比 - 比如說,類型檢查發生在宏擴展之前 - 雖然這需要做名稱解析並允許通過使用reify來添加*衛生。不要害怕:默認情況下,Scala宏不衛生,但是如果你只是通過reify生成AST來返回(這有點類似於準引用,我仍然沒有坦白地說明)。 – Blaisorblade