BLOCK 특수 연산자

BLOCK 특수 연산자 (block)

block은 Common Lisp의 특수 연산자로, 이름을 붙인 블록을 만들어 그 몸체를 차례로 평가하고, return-from과 함께 쓰면 블록 밖으로 한 번에 빠져나오는 구조화된 비지역 탈출(non-local exit)을 제공해요. 여러 겹으로 감싸인 함수나 루프 안에서 중간 단계를 건너뛰고 원하는 블록까지 바로 복귀해야 할 때 쓰는 도구랍니다.

출처: CLHS: Special Operator BLOCK

문법 (Syntax)

block name form* => result*

인자와 값 (Arguments and Values)

  • name — 기호(symbol)예요.
  • form — 형식(form)이에요.
  • results — 정상 복귀(normal return)가 일어나면 form들의 값이고, 명시적 복귀(explicit return)가 일어나면 그때 전달된 값이에요.

설명 (Description)

blockname이라는 이름의 블록을 세우고(establish), form들을 암시적 progn(implicit progn)으로 평가해요.

특수 연산자 blockreturn-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)

없음.

더 알아보기 (Learn more)