DEFINE-MODIFY-MACRO — place를 읽고 갱신하는 매크로 정의하기
DEFINE-MODIFY-MACRO — place를 읽고 갱신하는 매크로 정의하기 (매크로)
incf·push처럼 특정 place를 읽고 난 값을 다시 써 넣는 매크로를 손쉽게 정의하게 해주는 매크로예요. 새 값을 계산하는 함수만 정해주면, define-modify-macro가 "읽고 → 함수 적용하고 → 다시 써 넣는" 틀을 자동으로 만들어줘요.
시그니처 (Syntax)
define-modify-macro name lambda-list function [documentation] => name
name—symbol.lambda-list— define-modify-macro lambda list.function—symbol.documentation—string. 평가되지 않아요.
본문 (Description)
define-modify-macro는 name이라는 매크로를 정의해서 하나의 place를 read하고 write하게 해요.
새 매크로의 인자는 place 하나, 그 뒤에 lambda-list에 있는 인자들이 와요. define-modify-macro로 정의한 macro는 get-setf-expansion에 environment parameter를 올바르게 전달해요.
매크로가 호출되면 function을 해당 place의 이전 내용과 lambda-list 인자들에 적용해 새 값을 얻고, 그 결과가 들어가도록 place를 갱신해요.
다중 평가(multiple evaluation)를 피하는 문제(아래 참고)만 제외하면, define-modify-macro의 확장은 다음 코드와 동등해요:
(defmacro name (reference . lambda-list)
documentation
`(setf ,reference
(function ,reference ,arg1 ,arg2 ...)))
여기서 arg1, arg2, ... 는 lambda-list에 나타나는 매개변수예요. rest parameter도 알맞게 처리돼요.
define-modify-macro로 정의한 매크로 호출의 subform들은 Section 5.1.1.1 (Evaluation of Subforms to Places)에서 정한 대로 평가돼요.
documentation은 name에 function 종류의 documentation string으로, 그리고 macro function에도 붙어요.
define-modify-macro form이 top level form으로 나타나면 compiler는 매크로 정의를 컴파일 시점에 저장해서, 파일 뒤쪽에서 그 매크로가 나타나는 곳을 올바르게 확장할 수 있어야 해요.
예제 (Examples)
(define-modify-macro appendf (&rest args)
append "Append onto list") => APPENDF
(setq x '(a b c) y x) => (A B C)
(appendf x '(d e f) '(1 2 3)) => (A B C D E F 1 2 3)
x => (A B C D E F 1 2 3)
y => (A B C)
(define-modify-macro new-incf (&optional (delta 1)) +)
(define-modify-macro unionf (other-set &rest keywords) union)
Side Effects
name에 매크로 정의가 할당돼요.
더 알아보기 (See Also)
defsetf, define-setf-expander, documentation, Section 3.4.11 (Syntactic Interaction of Documentation Strings and Declarations)
Notes
없음.