2011-01-05 5 views
2

이 질문에 대한 대답은 this answer입니다.비 리터럴 시퀀스에 대한 연결 해제 인용 부호 없음

이 같은 접합 맺다을 사용하는 매크로가있는 경우 : values 리터럴 시퀀스 또는 SEQ-할 경우

(defmacro instantiate [klass values] 
     `(new ~klass [email protected])) 

그것은 단지 작동합니다. 이 같은 시퀀스를 들고 var에 전달되면

는 :

(def v [1 2 3]) 
(macroexpand '(instantiate Person v)) 

를 다음 출력은 v이 순서 아님을 나타내는 오류 일 것이다.

(defn vf [] [1 2 3]) 
(macroexpand '(instantiate Person (vf))) 
user=>(new Person vf) 

내 질문은 : 순서가 'ISN을 접합 할 두 경우에 Clojure의 매크로의 접합 맺다를 사용하는 방법은 없나요

는 심지어 함수 호출 목록으로 해석됩니다 문자 그대로?

답변

2

매크로는 평가되지 않은 인수를 수신하므로보고있는 동작이 의도 한 것과 같습니다.

매크로는 런타임이 아닌 컴파일 타임에 확장됩니다. 매크로에 전달 된 변수 값은 컴파일 타임에 사용할 수 없으므로 일반적인 경우에는 eval을 사용하는 것과 같은 더러운 해킹이 작동하지 않습니다. 이러한 트릭이 필요한 매크로를 만들지 마십시오. 그들이 일을 해달라고 할 때, 당신은 사물에게 옛날 방식을 할 필요가 제외

+0

그래서 때로는 가능하지 않으며, 다른 때에는 나쁜 생각입니다. 감사. –

1

접합 따옴표

(defmacro instantiate [klass values] 
    `(new ~klass [email protected])) 

이 될 수 ..., 거의 모든 경우에 많은 시간을 절약 할

(defmacro instantiate [klass values] 
    (concat (list 'new klass) (if (seq? values) 
            values 
            (list values)))) 

user=> (macroexpand '(instantiate asdf (1 2 3))) 
(new asdf 1 2 3) 

user=> (macroexpand '(instantiate asdf 1)) 
(new asdf 1) 
+0

매개 변수의 평가와 관련하여 실제 문제는 해결되지 않았지만 실제로이 문제가 어떻게 작용하는지 이해할 수있었습니다. 감사 –

관련 문제