這與Treat Clojure macro as a function中討論的問題類似,但在頂級答案中嘗試該方法時,出現錯誤。關於我的具體應用希望太多的信息是沒有必要的,因爲它是相當複雜的,但這裏是什麼,我試圖做一個蒸餾版本:Clojure宏作爲函數/'部分'爲宏?
(defmacro make-fn [m arg1]
`(fn [& args#]
(eval `(~'~m ~'~arg1 [email protected]#))))
我以前在這方面的宏:
(let [columns (make-columns table-width)
table-name (keyword (str "table_" n))]
(apply (make-fn helpers/tbl table-name) columns))
「helpers/tbl」是一個宏,它需要一個表名關鍵字和可變數量的包含列規格的列表(如[:varchar 100]或其他)。我試圖隨時創建隨機數據庫表規格以便於進行一些測試。總之,試圖執行上面的代碼時,我得到以下錯誤:
CompilerException java.lang.RuntimeException: Unable to resolve symbol: table-name in this context, compiling:(NO_SOURCE_PATH:1)
我有點把握的問題:宏展開在編譯時完成的,我想包括在運行時的值宏觀擴張,因此引用和不加引用的奇怪用法使得一切都設置恰到好處。我基本上想要一個宏的部分,我需要能夠在不同的命名空間中爲不同的宏重用這種機制,並且所有的可變分辨率都是正確的。這甚至有可能嗎?
BTW ,關於'syntax-quote'的有趣事實:它完全在讀者中實現。當讀者看到一個反引號時,它讀取下面的表格,然後遞歸地轉換成使用'seq','concat'和'list'的代碼。編譯器只能看到生成的'concat' /'list'代碼。 –