User Tools


Differences

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

Link to this comparison view

cl:functions:getf [2019/06/15 02:00]
cl:functions:getf [2019/11/19 12:00] (current)
Line 1: Line 1:
 +====== Accessor GETF ======
  
 +====Syntax====
 +  * **getf** //plist indicator// ''&​optional''​ //default// → //value//
 +  * (**setf** (**getf** //place indicator ''&​optional''​ default//) //​new-value//​)
 +
 +====Arguments and Values====
 +  * //plist// - a //​[[CL:​Glossary:​property list]]//.
 +  * //place// - a //​[[CL:​Glossary:​place]]//,​ the //​[[CL:​Glossary:​value]]//​ of which is a //​[[CL:​Glossary:​property list]]//.
 +  * //​indicator//​ - an //​[[CL:​Glossary:​object]]//​.
 +  * //default// - an //​[[CL:​Glossary:​object]]//​. The default is **[[CL:​Constant Variable:​nil]]**.
 +  * //value// - an //​[[CL:​Glossary:​object]]//​.
 +  * //​new-value//​ - an //​[[CL:​Glossary:​object]]//​.
 +
 +====Description====
 +**getf** finds a //​[[CL:​Glossary:​property]]//​ on the //plist// whose //​[[CL:​Glossary:​property indicator]]//​ is //​[[CL:​Glossary:​identical]]//​ to //​indicator//,​ and returns its corresponding //​[[CL:​Glossary:​property value]]//. If there are multiple //​[[CL:​Glossary:​property|properties]]//​ with that //​[[CL:​Glossary:​property indicator]]//,​ **getf** uses the first such //​[[CL:​Glossary:​property]]//​. If there is no //​[[CL:​Glossary:​property]]//​ with that //​[[CL:​Glossary:​property indicator]]//,​ //default// is returned.
 +
 +**[[CL:​Macros:​setf]]** of **getf** may be used to associate a new //​[[CL:​Glossary:​object]]//​ with an existing indicator in the //​[[CL:​Glossary:​property list]]// held by //place//, or to create a new assocation if none exists. If there are multiple //​[[CL:​Glossary:​properties]]//​ with that //​[[CL:​Glossary:​property indicator]]//,​ **[[CL:​Macros:​setf]]** of **getf** associates the //​new-value// ​ with the first such //​[[CL:​Glossary:​property]]//​. When a **getf** //​[[CL:​Glossary:​form]]//​ is used as a **[[CL:​Macros:​setf]]** //place//, any //default// which is supplied is evaluated according to normal left-to-right evaluation rules, but its //​[[CL:​Glossary:​value]]//​ is ignored.
 +
 +**[[CL:​Macros:​setf]]** of **getf** is permitted to either //​[[CL:​Glossary:​write]]//​ the //​[[CL:​Glossary:​value]]//​ of //place// itself, or modify of any part, //​[[CL:​Glossary:​car]]//​ or //​[[CL:​Glossary:​cdr]]//,​ of the //​[[CL:​Glossary:​list structure]]//​ held by //place//.
 +
 +====Examples====
 +<​blockquote>​
 +([[CL:​Macros:​defparameter]] *x* '()) <​r>​*X*</​r>​
 +(getf *x* '​prop1) <​r>​[[CL:​Constant Variable:​nil|NIL]]</​r>​
 +(getf *x* 'prop1 7) <​r>​7</​r>​
 +(getf *x* '​prop1) <​r>​[[CL:​Constant Variable:​nil|NIL]]</​r>​
 +([[CL:​Macros:​setf]] (getf *x* '​prop1) 'val1) <​r>​VAL1</​r>​
 +([[CL:​Functions:​eq]] (getf *x* '​prop1) 'val1) <​r>​[[CL:​Glossary:​true]]</​r>​
 +(getf *x* '​prop1) <​r>​VAL1</​r>​
 +(getf *x* 'prop1 7) <​r>​VAL1</​r>​
 +*x* <​r>​(PROP1 VAL1)</​r>​
 +([[CL:​Macros:​defparameter]] *foo* ([[CL:​Functions:​list]] 'a 'b 'c 'd 'e 'f)) <​r>​*FOO*</​r>​
 +([[CL:​Macros:​defparameter]] *bar* ([[CL:​Functions:​cddr]] *foo*)) <​r>​*BAR*</​r>​
 +([[CL:​Macros:​remf]] *foo* 'c) <​r>​[[CL:​Glossary:​true]]</​r>​
 +*foo* <r>(A B E F)</​r>​
 +*bar* 
 +<r>(C D E F)
 +//or// (C)
 +//or// ([[CL:​Constant Variable:​nil|NIL]])
 +//or// (C [[CL:​Constant Variable:​nil|NIL]])
 +//or// (C D)</​r>​
 +</​blockquote>​
 +
 +====Side Effects====
 +None.
 +
 +====Affected By====
 +None.
 +
 +====Exceptional Situations====
 +None.
 +
 +====See Also====
 +**[[CL:​Functions:​get|Function GET]]**, **[[CL:​Functions:​get-properties|Function GET-PROPERTIES]]**,​ **[[CL:​Macros:​setf|Macro SETF]]**, {\secref\FnFormsAsGenRefs}
 +
 +====Example Implementation====
 +To be done.
 +
 +====Notes====
 +There is no way (using **getf**) to distinguish an absent property from one whose value is //​default//;​ but see **[[CL:​Functions:​get-properties]]**.
 +
 +Note that while supplying a //​[[CL:​Glossary:​default]]//​ argument to **[[CL:​Macros:​getf]]** in a **[[CL:​Macros:​setf]]** situation is sometimes not very interesting,​ it is still important because some macros, such as **[[CL:​Macros:​push]]** and **[[CL:​Macros:​incf]]**,​ require a //place// argument which data is both //​[[CL:​Glossary:​read]]//​ from and //​[[CL:​Glossary:​write|written]]//​ to.  In such a context, if a //​[[CL:​Glossary:​default]]// ​ argument is to be supplied for the //​[[CL:​Glossary:​read]]//​ situation, it must be syntactically valid for the //​[[CL:​Glossary:​write]]//​ situation as well. For example,
 +
 +<​blockquote>​
 +([[CL:​Special Operators:​let]] ((plist '()))
 +  ([[CL:​Macros:​incf]] (getf plist 'count 0))
 +  plist) <​r>​(COUNT 1)</​r>​
 +</​blockquote>​
 +
 +
 +\issue{SETF-GET-DEFAULT:​EVALUATED-BUT-IGNORED}
 +\issue{REMF-DESTRUCTION-UNSPECIFIED:​X3J13-MAR-89}
 +\issue{PLIST-DUPLICATES:​ALLOW}