DEFINE-MODIFY-MACRO — place를 읽고 갱신하는 매크로 정의하기

DEFINE-MODIFY-MACRO — place를 읽고 갱신하는 매크로 정의하기 (매크로)

incf·push처럼 특정 place를 읽고 난 값을 다시 써 넣는 매크로를 손쉽게 정의하게 해주는 매크로예요. 새 값을 계산하는 함수만 정해주면, define-modify-macro가 "읽고 → 함수 적용하고 → 다시 써 넣는" 틀을 자동으로 만들어줘요.

출처: DEFINE-MODIFY-MACRO - Common Lisp HyperSpec

시그니처 (Syntax)

define-modify-macro name lambda-list function [documentation] => name
  • namesymbol.
  • lambda-listdefine-modify-macro lambda list.
  • functionsymbol.
  • documentationstring. 평가되지 않아요.

본문 (Description)

define-modify-macroname이라는 매크로를 정의해서 하나의 placeread하고 write하게 해요.

새 매크로의 인자는 place 하나, 그 뒤에 lambda-list에 있는 인자들이 와요. define-modify-macro로 정의한 macroget-setf-expansionenvironment 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)에서 정한 대로 평가돼요.

documentationnamefunction 종류의 documentation string으로, 그리고 macro function에도 붙어요.

define-modify-macro formtop 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

없음.