1
votes


Is there any way to make a defun in common-lisp change global variables? In the following example, is there any way to make foo have the value 3 from inside the function?

The example is from sbcl


  • (defparameter foo "foo")

FOO

  • foo

"foo"

  • (defun bar (y) (declare (special y)) (print y) (setf y 3) (print y))

BAR

  • (bar foo)

"foo"
3
3

  • foo

"foo"

1

1 Answers

6
votes

Yes. You can use setf (documented here) to set the value of all variables, including global ones. For example:

(defparameter foo "foo") ; => FOO
(defun bar () (setf foo 3)) ; => BAR
foo ; => "foo"
(bar) ; => 3
foo ; => 3

The reason your function was not altering the value of foo was because your setf form was setting the value of y rather than foo.

EDIT:

Ah, I think I see what you want to do here. You can use the set function to do this; (setq alpha "beta") is (roughly) equivalent to (set 'alpha "beta"). So, if we change our function to use set, we get:

(defparameter foo "foo")
(defun bar (sym) (set sym 3))
foo ; => "foo"
(bar 'foo)
foo ; => 3

Note that this isn't necessarily setting a global variable, though:

(defparameter baz 1)
(let ((baz 2))
  baz ; => 2
  (bar 'baz)
  baz) ; => 3
baz ; => 1