Reputation: 398
Acording to Accesor GET, get finds a property on the property list2 of symbol whose property indicator is identical to indicator, and returns its corresponding property value. If the property doesn't exists, it returns NIL.
Then, if
(get 'clyde 'species) => nil
the expression
(setf (get 'clyde 'species) 'elephant)
must be the same as
(setf nil 'elephant)
and fail, but it's not the case.
How it comes that the same get
produces a value in one case and a place in the other?
Edit
I found the answer here: How does using the SETF function to extend SETF work?
Upvotes: 0
Views: 351
Reputation: 9252
setf
is a macro: the job of a macro is to transform code to other code. So (setf (get ...) ...)
does not ever call get
: rather setf
's macro function looks at the code it is given and turns it into other code, which is (after any other macros get to do their work) called. Here is what (setf (get 'foo 'x) 3)
expands into in two implementations:
(setf (get 'foo 'x) 3)
-> (system::%put 'foo 'x 3)
(setf (get 'foo 'x) 3)
-> (ccl::set-get 'foo 'x 3)
As you can see, get
is not being called, and there is no reason why it would be in this case.
Upvotes: 0
Reputation: 60014
Please take a look at Places and Generalized References.
Basically, setf
is a macro, so
(setf (get 'clyde 'species) 'elephant)
is not evaluated sequentially as you seem to think it is, but instead expanded to whatever
(macroexpand '(setf (get 'clyde 'species) 'elephant))
returns in your implementation, and then the result is evaluated.
The bottom line is: when (setf (get 'clyde 'species) 'elephant)
is being evaluated, (get 'clyde 'species)
is not getting evaluated at all.
Upvotes: 2