2012-02-09 2 views
2

의 가정하자 :Common Lisp : 조건부 접합을 사용하여 매크로에서 목록을 작성하는 방법은 무엇입니까?

(defmacro testing (&optional var) 
    `(list 'this 'is 
     ,@(when (consp var) `('a 'list)))) 

전화했을 때 : 내가 원하는 무엇

>(testing 2) 
(THIS IS) 

>(testing (list 1 2)) 
(THIS IS A LIST) 

. 그러나 지금, 나는 목록입니다 매개 변수 통과 할 때 : 매크로 대신 목록으로, 즐이 기호는 (consp bla)을 확인 때문에 내 생각

>(defparameter bla (list 1 2 3)) 
BLA 
>(testing bla) 
(THIS IS) 

이를? 어떻게 이것을 막을 수 있습니까?

덕분에 여기

답변

4

당신이 뭔가를 할 수 있습니다. var은 매크로를 확장 할 때 한 번만 나타나지만 두 번 이상 나타나면 gensym을 사용해야합니다.

편집 : 두 번 '(this is)를 입력하지 않으려면 다음을 수행

(defmacro testing (&optional var) 
    `(append '(this is) (when (consp ,var) '(a list)))) 

eval를 사용하지 마십시오, 그것은 천천히, 완전히 불필요합니다. var을 매크로 확장으로 대체하면 실행시 자연스럽게 평가됩니다. 당신이 평가 사용하는 경우는 다음과 같이 뭔가를하고있을 것입니다 :

(eval (append '(list 'this 'is) (when (consp 'bla) '('a 'list)))) 

실행 모든 시간, 그것은 코드를 나타내는 목록을 구축하고 실행하기 전에 컴파일합니다. (잘하면이 루프에 없습니다!) 그냥 코드를 생성하는 매크로를 사용하는 경우 (eval 않고), 그것은 한 번만 컴파일됩니다.

+0

이것은 (매우 단순화 된)이 경우에 효과가 있지만 '(이것은) 조건부 스 플라이 싱으로 입력하지 않아도됩니다. – mck

+0

@mck, 그 요구 사항을 충족하는 코드를 게시했습니다. –

+0

고맙습니다. 우아한 해결책입니다. if를 when로 대체하고 nil을 삭제하면 더 짧아 질 수 있습니다 (false 일 때 nil을 반환). "실행시 자연스럽게 평가되는"것에 대한 질문이 하나 더 있습니다. 이 코드를 일부 코드에서 사용하면 목록을 멋지게 반환하지만 코드를 평가하지 못합니다. – mck

0

문제는 당신이 인수 만의 문자 (평가되지 않은) 값을 가질 때 표현

,@(when (consp var) `('a 'list)))) 

는, 컴파일시에 평가되는 것입니다. 귀하의 경우 : 2, (list 1 2)bla

내가 알고있는 이것에 대한 유일한 해결책은 eval을 사용하는 것입니다. 이 특별한 예는 다음과 같이 변경할 수 있습니다

(defmacro testing (&optional var) 
    `(eval (append '(list 'this 'is) 
       (when (consp ',var) 
        '('a 'list)))) 

을하지만, 내 생각, 당신은 동의 할 것이다, 그 정말 추한 것을. 그리고 어휘 변수를 사용하려면 작동하지 않습니다. 일반적으로 문제를 재구성 할 수있는 방법이 있으므로 그러한 헛소리는 필요하지 않습니다.

(defmacro testing (&optional var) 
    `(if (consp ,var) 
     '(this is a list) 
     '(this is))) 

그래서 var이 (시간을 컴파일되지 않음) 런타임에 평가됩니다

+0

고마워요, 그것은 트릭을합니다 ('consp는 가야한다고 생각하지만?). 나는 좀 더 우아하게하기를 바랬지 만, 실제로 그것을 재결정하려고 노력해야합니다. – mck

+0

견적과 관련하여 그것은 당신이 어떻게 데이터를 전달 하느냐에 달려 있습니다. 귀하의 경우에는 실제로 필요하지 않습니다. 사실입니다. 그러나 가끔 '경량'목록을 기대하는 매크로에서'(1 2 3)'을 보게 될 것입니다. –

+0

아, 저것은 실제로 좋은 지적입니다. – mck

관련 문제