prog1, prog2 — 첫 번째 폼의 값을 남기고 나머지 실행

prog1, prog2 — 첫 번째 폼의 값을 남기고 나머지 실행

여러 폼을 실행하면서, 부수 효과가 모두 일어난 뒤에도 처음(또는 두 번째) 폼의 값을 돌려주고 싶을 때가 있어요. prog1prog2매크로로, 순서대로 평가하되 prog1은 첫 폼의 값을, prog2는 두 번째 폼의 값을 남겨요.

출처: PROG1, PROG2 - Common Lisp HyperSpec

시그니처

prog1 first-form form* => result-1

prog2 first-form second-form form* => result-2

본문

인자와 값

  • first-form이고, 아래에서 설명하는 대로 평가돼요.
  • second-form이고, 아래에서 설명하는 대로 평가돼요.
  • forms암묵적 progn이고, 아래에서 설명하는 대로 평가돼요.
  • result-1first-form평가에서 나오는 주요 값(primary value) 이에요.
  • result-2second-form평가에서 나오는 주요 값이에요.

설명

prog1first-form을 평가하고 그다음 forms를 평가하면서, 유일한 으로 first-form이 내놓은 주요 값을 돌려줘요.

prog2first-form, 그다음 second-form, 그리고 forms를 평가하면서, 유일한 으로 second-form이 내놓은 주요 값을 돌려줘요.

예제

(setq temp 1) =>  1
(prog1 temp (print temp) (incf temp) (print temp))
>>  1
>>  2
=>  1
(prog1 temp (setq temp nil)) =>  2
temp =>  NIL
(prog1 (values 1 2 3) 4) =>  1
(setq temp (list 'a 'b 'c))
(prog1 (car temp) (setf (car temp) 'alpha)) =>  A
temp =>  (ALPHA B C)
(flet ((swap-symbol-values (x y)
         (setf (symbol-value x)
               (prog1 (symbol-value y)
                      (setf (symbol-value y) (symbol-value x))))))
  (let ((*foo* 1) (*bar* 2))
    (declare (special *foo* *bar*))
    (swap-symbol-values '*foo* '*bar*)
    (values *foo* *bar*)))
=>  2, 1
(setq temp 1) =>  1
(prog2 (incf temp) (incf temp) (incf temp)) =>  3
temp =>  4
(prog2 1 (values 2 3 4) 5) =>  2

Side Effects

없음.

Notes

prog1prog2는 보통 부수 효과가 있는 을 하나 이상 평가하면서, 일부 부수 효과가 일어나기 전에 계산해야 하는 을 돌려줄 때 써요.

(prog1 form*) ==  (values (multiple-value-prog1 form*))
(prog2 form1 form*) ==  (let () form1 (prog1 form*))

더 알아보기

  • multiple-value-prog1 — 첫 폼의 모든 값 남기기
  • progn — 순차 실행