General solution - destructive access to variable
I think, what you wanted to know is actually this:
(defparameter a 1)
(defmacro foo (x)
`(setf ,x (+ ,x 1))) ;; this macro takes the variable given for x
;; accesses its memory location using `setf`
;; and changes its value to 2
;; by increasing the accessed value by 1
(foo a) ;; a's value becomes 2
a ;; 2
However, as a beginner in common lisp, be careful to mutate wildly values around. Although I don't want to take you the joy of the power of Lisp. :)
Special solution - foo
= incf
But foo
(which increments a given value by 1)
is exactly incf
in common lisp, because this increment by one is often needed. So for this very special case, you can just use incf
.
(defparameter a 1)
a ;; => 1
(incf a) ;; incf mutates a to 2 - in exactly the way foo does
a ;; => 2 ;; a ist after that changed.
Note, there is also decf
which decrements the variable by 1 - the opposite of incf
.
Secial solution for global variables
But for global variables, you can use very normal defparameter
to reassign the value to a
:
(defparameter a 1)
(defparameter a (foo a)) ;; reassigns new value `2` to `a`
a ;; returns 2, since mutated now
Comment to the very first version:
(setf <var> <new-value>)
is like a pointer access to the variable's memory location and writing to it what is given for <new-value>
.
So in Lisp, you have to use a combination of defmacro
and setf
to imitate or actually do call-by-reference like in C or Python.
But you know from Python or C already, how un-anticipated side-effects call-by-reference can provoke. Python does by default call-by-reference due to performance reasons (because Python is interpreted and it would become very slow if doing call-by-value everytime a function is called). But with Lisp, you are/you can be at least whenever you want magnitudes faster than interpreted Python (Okay, I am simplifying - Python can of course call C function an be also super fast - however, pure Python of course would be by magnitudes slower than compiled Lisp). And you have many other possibilities to program the same thing. So don't try to imitate Python or other programs function call behaviour in Lisp - that is the wrong track.
Learn functional programming (FP) rules, which tries to not to mutate any values, but to do always call-by-value (like your function foo
does). It produces 2 but leaves a
the same. To reason about such programs is much more brain-friendly, thus can save you in many cases from avoidable bugs. FP is definitely sth you should learn, when dealing with Lisp btw. FP is amongst many other concepts sth what you learn when you learn Lisp - and I wouldn't want to miss it.
Destructive functions make only sense if state is really unavoidable and desired, and especially if performance is important.