# Differences

This shows you the differences between two versions of the page.

 cl:macros:shiftf [2019/08/16 12:00] cl:macros:shiftf [2019/12/09 00:00] (current) Line 1: Line 1: + ====== Macro SHIFTF ====== + + ====Syntax==== + * **shiftf** //​place''​+''​ newvalue// → //​old-value-1//​ + + ====Arguments and Values==== + * //place// - a //​[[CL:​Glossary:​place]]//​. + * //​newvalue//​ - a //​[[CL:​Glossary:​form]]//;​ evaluated. + * //​old-value-1//​ - an //​[[CL:​Glossary:​object]]//​ (the old //​[[CL:​Glossary:​value]]//​ of the first //place//). + + ====Description==== + **shiftf** modifies the values of each //place// by storing //​newvalue//​ into the last //place//, and shifting the values of the second through the last //place// into the remaining //places//. + + If //​newvalue//​ produces more values than there are store variables, the extra values are ignored. If //​newvalue//​ produces fewer values than there are store variables, the missing values are set to **[[CL:​Constant Variables:​nil]]**. + + In the form ''​(shiftf place1 place2 ... placen newvalue)'',​ the values in ''​place1''​ through ''​placen''​ are //​[[CL:​Glossary:​read]]//​ and saved, and ''​newvalue''​ is evaluated, for a total of ''​n+1''​ values in all. Values ''​2''​ through ''​n+1''​ are then stored into ''​place1''​ through ''​placen'',​ respectively. It is as if all the //places// form a shift register; the //​newvalue//​ is shifted in from the right, all values shift over to the left one place, and the value shifted out of ''​place1''​ is returned. + + For information about the //​[[CL:​Glossary:​evaluation]]//​ of //​[[CL:​Glossary:​subforms]]//​ of //places//, see section {\secref\GenRefSubFormEval}. + + ====Examples==== + <​blockquote>​ + ([[CL:​Macros:​defparameter]] *x* ([[CL:​Functions:​list]] 1 2 3)) <​r>​*X*​ + ([[CL:​Macros:​defparameter]] *y* '​trash) <​r>​*Y*​ + (shiftf *y* *x* (cdr *x*) '(hi there)) <​r>​TRASH + *x* (2 3) + *y* (1 HI THERE)​ + + ([[CL:​Macros:​setf]] *x* ([[CL:​Functions:​list]] 'a 'b 'c)) (A B C)​ + (shiftf ([[CL:​Functions:​cadr]] *x*) 'z) B + *x* (A Z C) + (shiftf ([[CL:​Functions:​cadr]] *x*) ([[CL:​Functions:​cddr]] *x*) 'q) Z + *x* (A (C) . Q) + ([[CL:​Macros:​defparameter]] *n* 0) <​r>​*N*​ + ([[CL:​Macros:​setf]] *x* ([[CL:​Functions:​list]] 'a 'b 'c 'd)) (A B C D) + (shiftf ([[CL:​Functions:​nth]] ([[CL:​Macros:​incf]] *n*) *x*) 'z) B + *x* (A Z C D) + ​ + + ====Affected By==== + **[[CL:​Macros:​define-setf-expander]]**,​ **[[CL:​Macros:​defsetf]]**,​ **[[CL:​Variables:​*macroexpand-hook*]]** + + ====Exceptional Situations==== + None. + + ====See Also==== + * **[[CL:​Macros:​setf|Macro SETF]]** + * **[[CL:​Macros:​rotatef|Macro ROTATEF]]** + * {\secref\GeneralizedReference} + + ====Notes==== + The effect of ''​(shiftf //place1// //place2// ... //placen// //​newvalue//​)''​ is roughly equivalent to + + <​blockquote>​ + ([[CL:​Special Operators:​let]] ((var1 //​place1//​) ​ + (var2 //​place2//​) ​ + ... + (varn //​placen//​) ​ + (var0 //​newvalue//​)) + ([[CL:​Macros:​setf]] //place1// var2) + ([[CL:​Macros:​setf]] //place2// var3) + ... + ([[CL:​Macros:​setf]] //placen// var0) + var1) + ​ + + except that the latter would evaluate any //​[[CL:​Glossary:​subforms]]//​ of each ''​place''​ twice, whereas **shiftf** evaluates them once. For example, + + <​blockquote>​ + ([[CL:​Macros:​defparameter]] *n* 0) 0 + ([[CL:​Macros:​defparameter]] *x* ([[CL:​Functions:​list]] 'a 'b 'c 'd)) (A B C D) + ([[CL:​Macros:​prog1]] ​ + ([[CL:​Functions:​nth]] ([[CL:​Macros:​incf]] *n*) *x*) + ([[CL:​Macros:​setf]] ([[CL:​Functions:​nth]] ([[CL:​Macros:​incf]] *n*) *x*) 'z)) B + *x* (A B Z D)​ + ​ + + \issue{SETF-MULTIPLE-STORE-VARIABLES:​ALLOW} \issue{PUSH-EVALUATION-ORDER:​FIRST-ITEM}