destructuring-bind — 리스트 구조를 한 번에 풀어 담기

destructuring-bind — 리스트 구조를 한 번에 풀어 담기

함수 인자를 받을 때는 lambda-list가 알아서 각 인자를 변수에 담아줘요. 그런데 지금 필요한 값이 함수 인자가 아니라, 리스트 안 깊은 곳에 들어 있는 값이라면 어떨까요? 매번 carcdr을 조합해 직접 풀어야 한다면 여간 번거롭지 않아요. destructuring-bind는 바로 그 자리에서 리스트 구조를 패턴에 맞춰 한꺼번에 변수로 풀어주는 매크로예요.

출처: CLHS 공식 문서 - DESTRUCTURING-BIND

본문

destructuring-bindlambda-list에 지정된 변수들을, expression을 평가해서 얻은 트리 구조의 값들에 대응시켜 묶은 다음 forms를 평가해요.

destructuring-bind lambda-list expression declaration* form*
=> result*

지정할 수 있는 lambda-list는 일반 함수의 인자 목록과 달리, 구조 분해(destructuring) 람다 리스트예요. 즉 리스트의 각 자리마다 (key &optional default) 같은 세부 패턴을 다시 넣을 수 있어요.

(defun iota (n) (loop for i from 1 to n collect i))  ; helper

(destructuring-bind ((a &optional (b 'bee)) one two three)
    `((alpha) ,@(iota 3))
  (list a b three two one))
=>  (ALPHA BEE 3 2 1)

백쿼트와 ,@(iota 3) 덕분에 전체 인자로 ((alpha) 1 2 3)이 넘어와요. 패턴의 첫 자리 (a &optional (b 'bee))(alpha)와 맞물리면서 a에는 alpha가, 지정되지 않은 b에는 기본값 bee가 들어가고, 나머지 one two three에는 1 2 3이 차례대로 담기죠.

예외 상황

평가 결과가 분해 패턴과 맞지 않으면 error 타입의 오류가 신호되어야 해요.

함께 보기

macrolet, defmacro