배열은 Common Lisp에서 아주 흔한 데이터 타입이에요.
배열은 cons 셀이 이어진 구조로 이루어져 있어요.
각 car는 배열의 원소이고, 각 cdr은 다음 cons 셀이거나 끝을 맺는 원자예요.
빈 배열로 끝나는 배열을 "올바른 배열"이라고 해요.
빈 배열이 아닌 원자로 끝나는 배열은 "점 표기 배열"이라고 해요(출력되는 모양을 보고 붙인 이름이에요: (cons 'a 'b) ;=> (a . b)).
배열 안의 어떤 cons 셀이 뒤에 오는 cons 셀을 cdr로 가리키면 그 배열은 순환 구조가 될 수도 있어요.
예를 들어: (let ((x (list 1))) (setf (cdr x) x) (write x :stream t :circle t) :done).
순환 배열을 다룰 때는 주의해야 해요. *print-circle*를 t로 바인딩하지 않은 채로 순환 배열을 출력하면 무한 루프에 빠져 REPL이 멈춰버려요(이 예제에서는 write에 :circle t를 지정했기 때문에 *print-circle이 t로 바인딩돼요).
append는 배열을 원하는 개수만큼 넘겨서 호출할 수 있어요. 하나만 넘겨도 되고 하나도 넘기지 않아도 돼요:
(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '())) ; => (A B C)
(append '(a b c)) ; => (A B C)
(append) ; => ()
append 대신 nconc를 쓸 수도 있어요. 결과는 같지만, 원래 배열을 수정하는 부작용이 있어요. nconc는 예상치 못한 결과를 낼 수 있으니 조심해서 사용해야 해요.