The error does not happen with the macro version, because, as you assumed, the expression (setf (get-x some-x some-list) some-value) will be expanded (at compile-time) into something like (setf (nth some-x some-list) some-value) (not really, but the details of setf expansion are complex), and the compiler knows, how to deal with that (i.e. , there is a suitable setf expander defined for function nth ) However, in the case of get-y the compiler has no setf expander, unless you provide one. The easiest way to do so would be (defun (setf get-y) (new-value x ls) ; Note the function's name: setf get-y (setf (nth x ls) new-value)) Note, that there are a few conventions regarding setf expanders: The new value is always provided as the first argument to the setf function All setf functions are supposed to return the new value as their result (as this is, what the entire setf form is supposed to return) There is, BTW, no such concept as a "reference" in Common Lisp (at least not in the C++ sense), though there once were Lisp dialects which had "locatives" (was the name, I think).
Generalized place forms (ie setf and its machinery) work very differently from plain C++ style references. See the CLHS, if you are curious about the details.
The error does not happen with the macro version, because, as you assumed, the expression (setf (get-x some-x some-list) some-value) will be expanded (at compile-time) into something like (setf (nth some-x some-list) some-value) (not really, but the details of setf-expansion are complex), and the compiler knows, how to deal with that (i.e. , there is a suitable setf expander defined for function nth). However, in the case of get-y, the compiler has no setf expander, unless you provide one.
The easiest way to do so would be (defun (setf get-y) (new-value x ls) ; Note the function's name: setf get-y (setf (nth x ls) new-value)) Note, that there are a few conventions regarding setf-expanders: The new value is always provided as the first argument to the setf function All setf functions are supposed to return the new value as their result (as this is, what the entire setf form is supposed to return) There is, BTW, no such concept as a "reference" in Common Lisp (at least not in the C++ sense), though there once were Lisp dialects which had "locatives" (was the name, I think). Generalized place forms (ie. , setf and its machinery) work very differently from plain C++ style references.
See the CLHS, if you are curious about the details.
I actually did not believe that there were references in Common Lisp in the C++ sense until now, thanks for clearing that up. I had to figure out an explanation for my problem so that was what I came up with. This whole thing with defining a function with a name like SETF GET-Y is kind of new to me as a concept... Anyway, I'll be doing some more research about this, thanks for your help!
– Johan May 2 at 13:05.
SETF is a macro. The idea is that to set and read elements from data structures are two operations, but usually require two different names (or maybe even something more complex). SETF now enables you to use just one name for both: (get-something x) Above reads a datastructure.
The inverse then simply is: (setf (get-something x) :foobar) Above sets the datastructure at X with :FOOBAR. SETF does not treat (get-something x) as a reference or something like that. It just has a database of inverse operations for each operation.
If you use GET-SOMETHING, it knows what the inverse operation is. How does SETF know it? Simple: you have to tell it.
For The NTH operation, SETF knows how to set the nth element. That's builtin into Common Lisp. For your own GET-Y operation SETF does not have that information.
You have to tell it. See the Common Lisp HyperSpec for examples. One example is to use DEFUN and (SETF GET-Y) as a function name.
Also note following style problems with your example: lst is not a good name for a DEFVAR variable. Use *list* as a name to make clear that it is a special variable declared by DEFVAR (or similar). '(1 2) is a literal constant.
If you write a Common Lisp program, the effects of changing it are undefined. If you want to change a list later, you should cons it with LIST or something like COPY-LIST.
1 Overlooked the mification of data provided as literals. – Dirk May 2 at 12:31 Yeah, I know that I indeed should use asterisks around global variables and so on, I was just very lazy and wanted to write what I wanted in the shortest way possible, my "real" code doesn't look like that. Thank you for your explanation!
– Johan May 2 at 13:04.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.