장식은 기본적으로 단지입니다 기능 .
일반적인 Lisp의 예 :
(defun attributes (keywords function)
(loop for (key value) in keywords
do (setf (get function key) value))
function)
위의 함수는 (에 의해 반환되는 DEFUN
) 심볼이며 심볼의 속성 목록 에 속성을 넣습니다 .
이제 함수 정의를 중심으로 작성할 수 있습니다.
(attributes
'((version-added "2.2")
(author "Rainer Joswig"))
(defun foo (a b)
(+ a b))
)
파이썬에서와 같이 멋진 구문을 추가하려면 리더 매크로를 작성하십시오 . 리더 매크로를 사용하면 s-expression 구문 레벨에서 프로그래밍 할 수 있습니다.
(set-macro-character
#\@
(lambda (stream char)
(let ((decorator (read stream))
(arg (read stream))
(form (read stream)))
`(,decorator ,arg ,form))))
우리는 다음과 같이 쓸 수 있습니다 :
@attributes'((version-added "2.2")
(author "Rainer Joswig"))
(defun foo (a b)
(+ a b))
Lisp 리더는 다음을 읽습니다.
(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
(AUTHOR "Rainer Joswig")))
(DEFUN FOO (A B) (+ A B)))
이제 Common Lisp 에 데코레이터 형식이 있습니다.
매크로와 리더 매크로의 결합.
실제로 함수가 아닌 매크로를 사용하여 실제 코드에서 위의 번역을 수행합니다.
(defmacro defdecorator (decorator arg form)
`(progn
,form
(,decorator ,arg ',(second form))))
(set-macro-character
#\@
(lambda (stream char)
(declare (ignore char))
(let* ((decorator (read stream))
(arg (read stream))
(form (read stream)))
`(defdecorator ,decorator ,arg ,form))))
동일한 리더 매크로에서 위와 같이 사용됩니다. 장점은 Lisp 컴파일러가 여전히 소위 최상위 양식 으로 간주한다는 점입니다 . * file 컴파일러는 최상위 양식을 특수하게 처리합니다 (예 : 컴파일 타임 환경 에 해당 양식에 대한 정보 추가) . 위의 예에서 매크로는 소스 코드를보고 이름을 추출 함을 알 수 있습니다.
Lisp 리더 는 위 예제를 다음과 같이 읽습니다.
(DEFDECORATOR ATTRIBUTES
(QUOTE ((VERSION-ADDED "2.2")
(AUTHOR "Rainer Joswig")))
(DEFUN FOO (A B) (+ A B)))
그러면 매크로가 다음으로 확장됩니다.
(PROGN (DEFUN FOO (A B) (+ A B))
(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
(AUTHOR "Rainer Joswig")))
(QUOTE FOO)))
매크로는 리더 매크로와 매우 다릅니다 .
매크로는 소스 코드를 전달 받고 원하는대로 수행 한 다음 소스 코드를 반환합니다. 입력 소스가 유효한 Lisp 코드 일 필요는 없습니다. 그것은 무엇이든 될 수 있으며 완전히 다르게 쓰여질 수 있습니다. 결과는 유효한 Lisp 코드 여야합니다. 그러나 생성 된 코드가 매크로를 사용하는 경우 매크로 호출에 포함 된 코드의 구문은 다시 다른 구문 일 수 있습니다. 간단한 예 : 일종의 수학 구문을 허용하는 수학 매크로를 작성할 수 있습니다.
(math y = 3 x ^ 2 - 4 x + 3)
이 표현식 y = 3 x ^ 2 - 4 x + 3
은 유효한 Lisp 코드가 아니지만 매크로는이를 구문 분석하고 유효한 Lisp 코드를 다음과 같이 반환 할 수 있습니다.
(setq y (+ (* 3 (expt x 2))
(- (* 4 x))
3))
Lisp에는 많은 다른 매크로 사용 사례가 있습니다.