2010-05-15 13 views
19

저는 (자체 학습으로) 일련의 정수에 함수를 적용하고 결과를 합산하는 코드를 생성하는 Clojure 매크로를 작성하려고합니다.Clojure 매크로에서 심볼 생성 제어하기

F (0) + F (1) + F (2) + F (3)

이 내 시도이다 : 그러나 뭔가 X 번호의 gensym와 잘못 갈 것으로 보인다

(defmacro testsum [func n] 
    `(fn [x#] (+ [email protected](map (fn [i] `(~func x#)) (range n))))) 

나는 X의 두 가지 버전으로 끝낼 따라서 기능이 작동하지 않습니다

(macroexpand '(testsum inc 3)) 

을 제공합니다

(fn* ([x__809__auto__] 
    (clojure.core/+ 
    (inc x__808__auto__) 
    (inc x__808__auto__) 
    (inc x__808__auto__)))) 

이것은 다른 809 및 808 버전의 x에서 별개로 원하는 것입니다 .....

내가 뭘 잘못하고 있니? 나는 자동 gensym이 목적의이 종류를 위해 단 하나 유일한 상징을 창조하기 위하여 의미되었다는 것을 생각했다? 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

24

foo#- 스타일 gensyms는 구문이 작성된 곳에서만 유효합니다. 코드에서 두 x#의 서로 다른 구문 인용 블록에서 생성됩니다

(defmacro testsum [func n] 
    (let [x (gensym "x")] 
    `(fn [~x] (+ [email protected](map (fn [i] `(~func ~x)) (range n)))))) 

그리고 매크로 확장 ((macroexpand '(testsum inc 3))) :

(defmacro testsum [func n] 
    `(fn [x#] (+ [email protected](map (fn [i] `(~func x#)) (range n))))) 
    ^- s-q1  ^-unquote  ^- s-q2 

사용, 명시 적 (gensym) 전화를이 문제를 해결하려면

(fn* ([x4966] (clojure.core/+ (inc x4966) (inc x4966) (inc x4966)))) 
+3

나중에 (gensym "x")'를'\'x #'로 바꾸는 것도 가능합니다. 주요 확장 - 생성 양식. –

+0

굉장한 미칼 - 완벽하게 많은 감사를드립니다! Java 세계에서 나온 후에도 심볼 주위에 아직도 머리를 쓰고 있습니다 .... – mikera

관련 문제