2008-11-11 3 views
5

매크로와 관련하여 가장 좋은 방법이 무엇인지 이해하는 데 여전히 어려움이 있습니다. 나는 비행 중에 패키지를 정의하는 매크로를 작성하려고 시도하고있다.Common Lisp의 초보자 : 즉석에서 패키지 정의를위한 매크로 질문

(defmacro def-dynamic-package (name) 
    `(defpackage ,(intern (string-upcase name) "KEYWORD") 
    (:use :common-lisp))) 

이는 등의 표현을 위해 잘 작동 :

(def-dynamic-package "helloworld") 

그러나이 같은 뭔가를 비참하게 실패

(defun make-package-from-path (path) 
    (def-dynamic-package (pathname-name path))) 

또는

(defun make-package-from-path (path) 
    (let ((filename (pathname-path))) 
    (def-dynamic-package filename))) 

내가 이해하는 방법을 가장 기본 매크로는 작동하지만 어떻게 작동합니까? 이걸 구현하면 나를 벗어날 수 있습니다.

답변

8

defpack은 매크로입니다. 따라서 런타임은 컴파일 타임이 아닌 런타임으로 확장됩니다. 원하는 것은 런타임에 새로운 패키지를 만들기 위해 호출되는 것입니다. 따라서 패키지 꾸러미은 아무 것도 할 수 없습니다.

다행히, 또한 함수로 defpackage의 기능을 제공합니다 make-package을,있다. 패키지 대신 사용하십시오.

+0

아, 이것은 내가 매크로를 디자인 한 문제 중 하나 였는데, defpackage 자체가 매크로 였기 때문에 좋은 접근 방법을 추론하기가 어려웠다. 고마워. – dnolen

+2

사실, 그것은 패키지 패키지를 제공하는 defpackage이다. 유용한 매크로로 기능 :-) –

0

인수가 평가되지 않아야 할 때 매크로가 사용되기 때문에 여기서는 오류가 예상됩니다. 첫 번째 메이크업 패키지에서 경로에서

는 DEF-동적 패키지는 인자로 다음 식의 값과 같은 목록이 나타납니다 귀하의 경우

(list 'pathname-name 'path) 

을, 당신 당신이 CLHS을 선택하면

(defun def-dynamic-package (name) 
    (defpackage (string-upcase name) 
    (:use :common-lisp))) 

BTW, 당신은 defpackage의 첫 번째 인수가 상징 할 필요는 것을 알 수 있지만, 어떤 string designator : 만 기능을합니다.

+0

고맙습니다. Common Lisp을 배우는 것이 매크로를 사용하지 않을 때와 사용하지 않을시기를 배우는 것에 대해 많은 생각을했습니다. – dnolen

+0

당신이하는 일은 "(STRING-UPCASE NAME)"이라는 패키지를 정의하는 것입니다. 적어도 목록이 유효한 문자열 지정자 일 경우 당신이하고 있던 일이 될 것입니다. 어쨌든 코드는 이식 가능하지 않습니다. –

+0

몇 가지 문제 : a) def *는 일반적으로 매크로의 이름을 지정하고 b)는 Make-PACKAGE에 대한 Matthias의 대답을 참조하십시오. (DEFPACKAGE가 첫 번째 인수를 평가하지 않기 때문에 함수가 작동하지 않습니다. –