AND 매크로

AND 매크로 (and)

and는 여러 조건을 왼쪽에서 오른쪽으로 검사하면서, 처음으로 거짓(nil)이 나오는 지점에서 멈추는 매크로예요. 다른 언어의 &&와 비슷한데, Common Lisp의 and는 매크로이고 단락(short-circuit) 평가와 함께 '마지막 폼의 값'을 그대로 돌려주는 특징이 있어요.

출처: CLHS: Macro AND

문법 (Syntax)

and form* => result*

인자와 값 (Arguments and Values)

  • form — 폼이에요.
  • results — 마지막 form의 평가 결과로 나오는 값들이거나, 심볼 nil 또는 t예요.

설명 (Description)

and 매크로는 각 form을 왼쪽에서 오른쪽으로 하나씩 평가해요. 어떤 form이 곧바로 nil로 평가되면, 남은 form평가하지 않고 nil을 돌려줘요. 마지막 form을 제외한 모든 form이 참 값으로 평가되면, and는 마지막 form의 평가 결과를 돌려줘요.

form이 하나도 없으면 (and)t를 돌려줘요. 이는 참 값이 아니라 '거짓이 없다'는 뜻의 관례인데, Common Lisp에서 (and)를 항상 참인 식으로 취급해요.

and는 마지막 하위 폼에서 나온 다중 값만 돌려주고, 마지막이 아닌 하위 폼들의 값은 돌려주지 않아요.

예제 (Examples)

(if (and (>= n 0)
         (< n (length a-simple-vector))
         (eq (elt a-simple-vector n) 'foo))
    (princ "Foo!"))

위 표현식은 a-simple-vectorn 번째 원소가 심볼 foo이면 Foo!를 출력해요. 이때 n이 실제로 a-simple-vector의 유효한 인덱스여야 한다는 조건도 함께 붙어요. and가 좌→우 검사를 보장하므로, n이 범위 밖이면 elt가 호출되지 않아요. 즉 인덱스 검사와 원소 접근을 안전하게 묶을 수 있는 이유가 여기서 나와요.

(setq temp1 1 temp2 1 temp3 1) =>  1 
(and (incf temp1) (incf temp2) (incf temp3)) =>  2 
(and (eql 2 temp1) (eql 2 temp2) (eql 2 temp3)) =>  true
(decf temp3) =>  1 
(and (decf temp1) (decf temp2) (eq temp3 'nil) (decf temp3)) =>  NIL 
(and (eql temp1 temp2) (eql temp2 temp3)) =>  true
(and) =>  T 

두 번째 andNIL을 돌려주는 예제가 흥미로워요. (decf temp1)이 0(거짓)을 만들면서 and가 즉시 NIL을 반환해서, 남은 (decf temp2)·(decf temp3)는 실행되지 않아요. 값뿐 아니라 부수 효과까지 단락된다는 점을 보여줘요.

영향 (Affected By)

없음.

예외 상황 (Exceptional Situations)

없음.

함께 보기 (See Also)

  • cond, every, if, or, when

참고 (Notes)

다음은 and의 확장을 보여주는 동치식이에요.

(and form) ==  (let () form)
(and form1 form2 ...) ==  (when form1 (and form2 ...))

더 알아보기 (Learn more)