2015-01-14 3 views
1

나는 람다로 확장되는 매크로 (Doug Hoyte의 것)를 기반으로 공통 리스프 내의 scheme의 단일 네임 스페이스를 에뮬레이션하려고하는데, f! 심볼 (Doug Hoyte 's o!g! 기호)가 동일한 표현식으로 확장되지만 각 호출의 함수 위치에 funcall이 추가됩니다. 예를 들어 :Common Lisp Lisp-1 매크로

(fplambda (f!z x) (f!z x x)) 

확장 할에 :

(LAMBDA (F!Z X) (FUNCALL F!Z X X)) 

매크로는 현재 다음과 같습니다

(defmacro fplambda (parms &body body) 
    (let ((syms (remove-duplicates 
       (remove-if-not #'f!-symbol-p 
           (flatten body))))) 
    `(lambda ,parms 
     (macrolet ,(mapcar 
       (lambda (f) 
       `(,f (&rest parmlist) `(funcall ,',f ',@parmlist))) 
       syms)) 
     ,@body))) 

하지만 지금까지 내가 볼 수있는 (이 확장 위의 입력 제공) :

(LAMBDA (F!F X) 
     (MACROLET ((F!F (&REST PARMLIST) `(FUNCALL ,'F!F ',@PARMLIST)))) 
     (F!F X X)) 

매크로 릿 정의에서 F! F는 인용되거나 인용되지 않아야하며 parmlist는 인용 부호로 묶여서는 안됩니다. 무슨 일 이니? 미리 감사드립니다.

답변

4

귀하의 정의가 대부분 옳습니다. 방금 두 가지 간단한 실수를했습니다. 첫 번째 것은 일치하지 않는 팸입니다. 매크로 렛은 본문을 포함하지 않습니다 (출력에서 매크로 렛과 본문은 같은 들여 쓰기 수준에 있습니다).

중첩 된 역 인용 부호의 경우 유일한 실수는 parmlist 앞에있는 인용문입니다. 그 외 모든 것은 정확합니다. F! F 앞에 쉼표와 따옴표가 실제로 맞습니다. hyperspec : "구현시 역순으로 표시된 양식 F1을 평가할 때 위의 정의에서 암시 한 결과와 동일한 결과를 생성하는 임의의 양식 F2로 자유롭게 해석 할 수 있습니다." 안쪽 역 인용 부호가 아직 확장되지 않았으므로 따옴표와 인용 부호가 없어야합니다. `(, 'x)는 실제로`(x)와 같다.

중첩 된 역 따옴표는 악명 높게 복잡합니다. 아마도 그들을 이해하는 가장 쉬운 방법은 Steele's explanation of them을 읽는 것입니다.

편집 :

이 함수 위치에 fplambda 식을 사용할 수 없음인지 여부에 대한 질문에 대한 답변. hyperspec that deals with the evaluation of code의 부분에서 : "복합 형의 자동차가 상징이 아니라면 그 차는 람다 식이어야합니다.이 경우 복합 형은 람다 형식입니다." 폼의 자동차 (fplambda ...)는 람다식이 아니기 때문에 코드는 더 이상 유효한 Common Lisp 코드가 아닙니다.

내가 알아 낸 해결 방법이 있지만 추한 것 같습니다. 당신은 당신이 ([fplambda ...] ...) 같은 것을 쓸 수 있도록하는 reader macro을 정의하고 당신이 원하는 것을 할 것

((LAMBDA (&REST #:G1030) (APPLY (FPLAMBDA ...) #:G1030)) ...) 

로 읽을 수 있습니다. 여기에 당신이 그렇게 할 수 있도록 코드입니다 : 내가 생각할 수있는

(set-macro-character #\[ 'bracket-reader) 
(set-macro-character #\] (get-macro-character #\))) 

(defun bracket-reader (stream char) 
    "Read in a bracket." 
    (declare (ignore char)) 
    (let ((gargs (gensym))) 
    `(lambda (&rest ,gargs) 
     (apply ,(read-delimited-list #\] stream t) 
       ,gargs)))) 

다른 유일한 해결책은 코드 워커의 일종 (내가 거기에 당신을 도울 수)를 사용하는 것입니다.

+0

고마워요! 나는 그것을 확실히 읽을 것이다. 내 똑똑한 뻔뻔스런 생각은 분명히 그들이 생각하는 것처럼 영리하지 못합니다. – DJD

+0

그게 효과가 있지만 매크로를 사용하는 경우 그것은 함수 위치에 때 확장되지 않는 것 : ((fplambda ...) x y). 이 주위에 어떤 방법이 있습니까? – DJD