BLOCK 특수 연산자
BLOCK 특수 연산자 (block)
block은 Common Lisp의 특수 연산자로, 이름을 붙인 블록을 만들어 그 몸체를 차례로 평가하고, return-from과 함께 쓰면 블록 밖으로 한 번에 빠져나오는 구조화된 비지역 탈출(non-local exit)을 제공해요. 여러 겹으로 감싸인 함수나 루프 안에서 중간 단계를 건너뛰고 원하는 블록까지 바로 복귀해야 할 때 쓰는 도구랍니다.
문법 (Syntax)
block name form* => result*
인자와 값 (Arguments and Values)
name— 기호(symbol)예요.form— 형식(form)이에요.results— 정상 복귀(normal return)가 일어나면form들의 값이고, 명시적 복귀(explicit return)가 일어나면 그때 전달된 값이에요.
설명 (Description)
block은 name이라는 이름의 블록을 세우고(establish), form들을 암시적 progn(implicit progn)으로 평가해요.
특수 연산자 block과 return-from은 함께 동작해서 구조화되고 어휘적이며 비지역적인 탈출 기능을 제공해요. form 안에 어휘적으로 포함된 지점이라면 어디서든 return-from을 해당 name과 함께 쓰면 그 블록 폼에서 제어와 값을 돌려받을 수 있어요. 단, 그 사이에 같은 이름의 블록이 새로 세워져 있으면 안 되는데, 그 경우 바깥쪽 블록은 안쪽 블록에 가려(shadow)져 버려요.
name으로 붙인 블록은 어휘적 유효 범위(lexical scope)와 동적 지속(dynamic extent)을 가져요. 그리고 한 번 세워진 블록은 정상 복귀든 명시적 복귀든 딱 한 번만 빠져나갈 수 있어요.
예제 (Examples)
(block empty) => NIL
(block whocares (values 1 2) (values 3 4)) => 3, 4
(let ((x 1))
(block stop (setq x 2) (return-from stop) (setq x 3))
x) => 2
(block early (return-from early (values 1 2)) (values 3 4)) => 1, 2
(block outer (block inner (return-from outer 1)) 2) => 1
(block twin (block twin (return-from twin 1)) 2) => 2
;; Contrast behavior of this example with corresponding example of CATCH.
(block b
(flet ((b1 () (return-from b 1)))
(block b (b1) (print 'unreachable))
2)) => 1
마지막 예시가 잘 보여주는 부분이 있어요. flet으로 정의한 함수 b1 몸체 안의 return-from b는 바깥쪽 block b를 가리켜요. 함수 정의 몸체는 어휘적으로 바깥 블록 안에 있기 때문에, 안쪽의 block b에 가려지지 않거든요. 그래서 unreachable은 출력되지 않고 1이 반환돼요. 이 동작을 catch의 대응 예시와 대조해 보면, 비지역 탈출이 어휘적(lexical)으로 동작한다는 뜻이 더 또렷해져요.
영향 (Affected By)
없음.
예외 상황 (Exceptional Situations)
없음.
함께 보기 (See Also)
return,return-from- Section 3.1 (Evaluation)
참고 (Notes)
없음.