0

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?

Candid Moe
  • 131
  • 1
  • 9
  • Your logic doesn't follow. Suppose you have a variable `x` and it currently holds `nil`. Do you conclude that `(setf x 42)` doesn't make sense because it's setting `nil` to 42? No, you're setting the `x` variable to a new value 42. A place expression only denotes the contents when it is used to access the value; when a place expression is the target of store, then it doesn't simply denote the contents. It also denotes a location where the new contents will go. – Kaz Feb 17 '22 at 22:19

2 Answers2

2

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.

sds
  • 58,617
  • 29
  • 161
  • 278
  • I'm aware of `setf` being a macro and expanded, but why the same expression produce two different results?. – Candid Moe Feb 15 '22 at 20:17
  • when `(setf (get 'clyde 'species) 'elephant)` is being evaluated, `(get 'clyde 'species)` is not getting evaluated at all. – sds Feb 15 '22 at 20:35
0

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.

ignis volens
  • 7,040
  • 2
  • 12
  • Why not `(setf 'foo 'x 3)` instead? – Candid Moe Feb 16 '22 at 11:51
  • @CandidMoe: apart from any other reason the syntax of `setf` is `(setf [ ...])`: it takes an even number of arguments (in fact `(setf)` is legal as well: the even number of arguments can be zero). – ignis volens Feb 16 '22 at 13:19