SHIFTF — 장소들의 값을 왼쪽으로 밀어 넣는 매크로
SHIFTF — 장소들의 값을 왼쪽으로 밀어 넣는 매크로
여러 장소(place)의 값들을 shift register처럼 밀어 주는 매크로예요. 오른쪽 끝으로 새 값을 넣고 나머지 값들은 한 칸씩 왼쪽으로 옮겨, 맨 앞자리에서 밀려 나온 값을 돌려줘요.
시그니처
shiftf place+ newvalue => old-value-1
본문
인자와 값 (Arguments and Values)
place— place.newvalue— 폼(form); 평가돼요.old-value-1— 객체(첫 번째place의 옛 값).
설명 (Description)
shiftf는 각 place의 값을, 마지막 place에는 newvalue를 저장하고 두 번째부터 마지막까지의 값을 남은 place들로 밀어 넣는 방식으로 수정해요.
newvalue가 저장 변수보다 많은 값을 만들어내면 남는 값은 무시돼요. 반대로 newvalue가 저장 변수보다 적은 값을 만들면 없는 값은 nil로 채워져요.
(shiftf place1 place2 ... placen newvalue) 형태에서 place1부터 placen까지의 값을 읽어 저장하고, newvalue를 평가해 총 n+1개의 값을 만들어요. 그다음 값 2부터 n+1까지를 각각 place1부터 placen에 저장해요. 모든 place들이 shift register를 이루는 것처럼, newvalue는 오른쪽에서 밀려 들어오고 모든 값이 왼쪽으로 한 칸씩 이동하며, place1에서 밀려 나온 값이 반환되는 거예요.
place의 하위 폼(subform) 평가에 대한 정보는 Section 5.1.1.1 (Evaluation of Subforms to Places)를 보세요.
예제 (Examples)
(setq x (list 1 2 3) y 'trash) => TRASH
(shiftf y x (cdr x) '(hi there)) => TRASH
x => (2 3)
y => (1 HI THERE)
(setq x (list 'a 'b 'c)) => (A B C)
(shiftf (cadr x) 'z) => B
x => (A Z C)
(shiftf (cadr x) (cddr x) 'q) => Z
x => (A (C) . Q)
(setq n 0) => 0
(setq x (list 'a 'b 'c 'd)) => (A B C D)
(shiftf (nth (setq n (+ n 1)) x) 'z) => B
x => (A Z C D)
영향 (Affected By)
define-setf-expander, defsetf, *macroexpand-hook*.
특이 상황 (Exceptional Situations)
없음.
참고 (Notes)
(shiftf place1 place2 ... placen newvalue)의 효과는 대략 이와 동등해요:
(let ((var1 place1)
(var2 place2)
...
(varn placen)
(var0 newvalue))
(setf place1 var2)
(setf place2 var3)
...
(setf placen var0)
var1)
단, 후자는 각 place의 하위 폼을 두 번 평가하는 반면, shiftf는 한 번만 평가해요. 예를 들어,
(setq n 0) => 0
(setq x (list 'a 'b 'c 'd)) => (A B C D)
(prog1 (nth (setq n (+ n 1)) x)
(setf (nth (setq n (+ n 1)) x) 'z)) => B
x => (A B Z D)
더 알아보기
setf— 장소에 값을 넣는 매크로rotatef— 장소들의 값을 회전시키는 매크로