RETURN-FROM 특수 연산자
RETURN-FROM 특수 연산자 (return-from)
return-from은 이름 있는 블록(block)을 떠나 그 자리로 제어권을 되돌리는 특수 연산자예요. 같은 규모의 return이 가장 안쪽 블록에만 반응한다면, return-from은 블록에 이름을 붙여서 렉시컬(lexical)로 감싸여 있는 어떤 블록이든 지정해서 빠져나갈 수 있게 해줘요.
문법 (Syntax)
return-from name [result] =>
인자와 값 (Arguments and Values)
name— 블록 태그(block tag)이며, 평가되지 않아요.result— 폼(form)이며, 평가돼요. 기본값은nil이에요.
설명 (Description)
return-from은 렉시컬로 감싸여 있는 block에서 제어권과 **다중 값(multiple values)**을 되돌려 보내요.
name이라는 이름의 block 폼이 return-from이 쓰인 지점을 렉시컬로 감싸고 있어야 해요. result의 평가가 만드는 모든 값은, 그런 블록 중에서 가장 안쪽에 있는 것을 기준으로 즉시 반환돼요.
return-from이 시작하는 제어 이동은 Section 5.2 (Transfer of Control to an Exit Point)에서 설명하는 방식대로 진행돼요.
예제 (Examples)
(block alpha (return-from alpha) 1) => NIL
(block alpha (return-from alpha 1) 2) => 1
(block alpha (return-from alpha (values 1 2)) 3) => 1, 2
(let ((a 0))
(dotimes (i 10) (incf a) (when (oddp i) (return)))
a) => 2
(defun temp (x)
(if x (return-from temp 'dummy))
44) => TEMP
(temp nil) => 44
(temp t) => DUMMY
(block out
(flet ((exit (n) (return-from out n)))
(block out (exit 1)))
2) => 1
(block nil
(unwind-protect (return-from nil 1)
(return-from nil 2)))
=> 2
(dolist (flag '(nil t))
(block nil
(let ((x 5))
(declare (special x))
(unwind-protect (return-from nil)
(print x))))
(print 'here))
>> 5
>> HERE
>> 5
>> HERE
=> NIL
(block alpha (return-from alpha (values 1 2)) 3)이 1, 2를 돌려주는 예제를 보면, return-from이 값을 여러 개(다중 값) 그대로 반환한다는 사실이 드러나요. block out과 flet 예제에서는 exit 함수가 이름 있는 바깥 블록을 콕 집어서 빠져나가는 모습을 확인할 수 있어요.
아래 코드는 결과가 정의되지 않는 경우예요. block 폼이 return-from 폼이 시도되기 전에 정상적으로 끝나버리기 때문이에요.
(funcall (block nil #'(lambda () (return-from nil)))) is an error.
영향 (Affected By)
없음.
예외 상황 (Exceptional Situations)
없음.
함께 보기 (See Also)
block,return, Section 3.1 (Evaluation)
참고 (Notes)
없음.