我正在探索基本示例的宏,我不明白它是如何工作的。Clojure:爲什麼這個宏不起作用?
此:
(defmacro evalf [f v]
(f v))
(evalf + 2)
不起作用。
我想:
(defmacro evalf [f v]
'(f v))
(evalf + 2)
沒有運氣...
我不明白其他語法:~~ @等等,但他們也不管用。我看到符號f沒有指向+,但我不知道要說「取f是+的值」。
你能說清楚嗎? 預先感謝
我正在探索基本示例的宏,我不明白它是如何工作的。Clojure:爲什麼這個宏不起作用?
此:
(defmacro evalf [f v]
(f v))
(evalf + 2)
不起作用。
我想:
(defmacro evalf [f v]
'(f v))
(evalf + 2)
沒有運氣...
我不明白其他語法:~~ @等等,但他們也不管用。我看到符號f沒有指向+,但我不知道要說「取f是+的值」。
你能說清楚嗎? 預先感謝
取決於你想做的事做有兩個變種:
第一個(你可能想要的)是:
(defmacro evalf [f v] `(~f ~v))
或
(defmacro evalf [f v] (list f v))
它們都做同樣的事情:生成你需要的s表達式。 編譯時將(evalf + 10)
擴展爲(+ 10)
,然後在運行時成功進行評估。
第二個是這樣的:
(defmacro evalf [f v] ((resolve f) v))
現在的功能f
將稱爲在編譯時間,所以宏將擴大到結果:10
您與(f v)
變種默默地失敗,因爲當你撥打(evalf + 10)
, +
這裏只是一個普通符號,而不是從宏觀角度來看函數的引用,所以它試圖調用('+ 10)
,因爲clojure中的符號具有函數的語義,所以它是完全正確的語法,但是這個調用產生了nil
。 (符號調用的例子:('+ {'+ 10})
=> 10)所以如果你想得到這個命名爲這個符號的函數,你將不得不解決它,就像我的第二個例子。
而且隨着'(f v)
變異只是擴展到兩個符號列表:'f
和'v
,然後導致運行時調用('f 'v)
也返回nil
,就像第一種變體。
嘗試
(defmacro evalf [f v]
(list f v))
(evalf (partial * 2) 66); 132
在evalf
(partial * 2)
和66
所述呼叫;(list '(partial * 2) '66)
;
((partial * 2) 66)
132
。一種替代,使用語法報價,是
(defmacro evalf [f v]
`(~f ~v))
謝謝,都是答案,但我更瞭解你的,所以我選擇了這個 –