2013-08-24 5 views
2

편집 : 내 예에서 =>은 "평가 대상"을 의미하고 ->은 "macroexpand-1 이하로 확장"을 의미합니다.Common Lisp에서 쉼표 쉼표를 해석하는 방법은 무엇입니까?

Common Lisp에서 중첩 된 역 인용 부호를 사용하여 머리를 감싸려고하고 있는데, 다른 여러 가지 질문 덕분에 그것을 아주 잘 이해하고 있다고 생각합니다. 나는 그들을 보았다). 저에게 잔소리 한 일이 있습니다. 고려 : CLHS 다시 인용 형태의 확장을위한 알고리즘에 따라

`(a `(b ,,@(list 'c 'd))) 

=> (a `(b ,c ,d)) 

, 내가 줄 않는 확장에서 얻은 양식을 평가, 실제로 위의 첫 번째 양식의 (읽기 시간) 확장 과정을 강화하고, 동일한 결과. 자, 훌륭한 책에 Peter Seibel이 제시 한 once-only의 정의를 생각해보십시오.

(once-only (from to) 
    `(do ((,var ,from (next-prime (+ 1 ,var)))) 
     ((>= ,var ,to)) 
    ,@body))) 

-> (LET ((#:G939 (GENSYM)) (#:G940 (GENSYM))) 
    `(LET ((,#:G939 ,FROM) (,#:G940 ,TO)) 
     ,(LET ((FROM #:G939) (TO #:G940)) 
     `(DO ((,VAR ,FROM (NEXT-PRIME (+ ,1 ,VAR)))) ((>= ,VAR ,TO)) ,@BODY)))) 

이제 내 문제는 확장 된 형태의 두 번째 라인이다 : 그 정의 감안할 때

(defmacro once-only ((&rest names) &body body) 
    (let ((gensyms (loop for n in names collect (gensym)))) 
    `(let (,@(loop for g in gensyms collect `(,g (gensym)))) 
     `(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n))) 
     ,(let (,@(loop for n in names for g in gensyms collect `(,n ,g))) 
      ,@body))))) 

는 SBCL은 다음과 같은 매크로 확장을 보여줍니다. 그럴 필요가 없습니다 :

`(LET (,(,#:G939 ,FROM) ,(,#:G940 ,TO)) 

?

위의 첫 번째 예에서 ,,@의 평가가 목록에서 연결 한 요소에 쉼표를 "배포"하는 것을 확인하십시오 (c d)? 왜 여기에 그런 일이 일어나지 않습니까? 두 예제는 같은 구조를 공유하는 것처럼 보이지만 평가 된 결과는 일관성이 없습니다.

답변

0

나는 내 실수를 봅니다. 위의 매크로 확장의 두 번째 줄은 실제로는 다음과 같아야합니다.

`(LET (,`(,#:G939 ,FROM) ,`(,#:G940 ,TO)) 

이는 SBCL이 보여주는 것과 같습니다.

관련 문제