Re: Passing Global Variables Urgh.



landspeedrecord wrote:

Total newbie question....

First off... I know I am not supposed to use global variables in Lisp,
however...

Can anyone explain to me why the following bit of code doesn't work?
I don't get it and I think it is because there is something very
fundamental I do not understand about Lisp.

CM> (defvar *x* "blargh")
*X*

CM> *x*
"blargh"

CM> (defun test2 (x)

x is a lexical (local) variable here.

(setq x "orrgoaarghhh"))

This line ^ sets the value of a local variable.

TEST2

CM> (test2 *x*)
"orrgoaarghhh"

CM> *x*
"blargh"

It is not surprising that the value of an unrelated
dynamic (global) variable is unchanged. IOW, just because
you pass the _value_ of *x* to test2, does not magically
create any relationship between the dynamic variable *x*
and the lexical variable x. (Having both of these symbols
be based on the letter 'x' could possibly contribute to
one's confusion. Would you expect test2 to work the same
way if its parameter were named 'frobnitz'? Why or why not?)

My only guess is that the function "test2" gets passed a copy of the
global variable that is exists inside the function "test2".

It gets passed the _value_ of the global variable. So at
the beginning of test2, *x* and x probably refer to the
same string in memory. But then you change x to refer
to some other string "orrgoaarghhh". *x* still refers
to whatever it referred to before.

But isn't
the whole point of Defvar & Defparameter to create a global variable
that can be accessed from anywhere? If a copy of a global variable is
always passed into functions what good is a global variable?

You have to refer to the global (dynamic) variable, which is *x*.

Now I could write "test2" so that it was:
(defun test2 ()
(setq *x* "orrgoaarghhh"))

Right. This is generally how dynamic variables are used.

but that isn't the same as passing the global variable.

It sounds like you're expecting parameters to act like
&references in C++. They don't; they're just names of
lexical variables (unless explicitly declared dynamic).

You can achieve a similar effect by passing the name of a
dynamic variable:

(defun test3 (x)
(set x "a string"))

(test3 '*x*)

*x*
>>> "a string"

In Lisp, a variable is just a name for a storage location.
You can't pass a variable, as such, to anything; only
its name. It's rarely necessary to do that, though.

HTH,

-- JK

--
(declare (antichrist i) (anarchist i)) ; -- the sexp-pistols
.



Relevant Pages

  • Re: Global variables done right
    ... Lisp for the first time. ... deficiencies in the design of Common Lisp. ... three problems with CL's design when it comes to global variables: ... a conforming implementation of Common Lisp could expand DEFCONSTANT ...
    (comp.lang.lisp)
  • Re: Global variables done right
    ... design of Common Lisp. ... There are no global lexicals. ... all global variables should have named that are bookended by asterisks. ...
    (comp.lang.lisp)
  • Re: Global variables done right
    ... design of Common Lisp. ... There are no global lexicals. ... all global variables should have named that are bookended by asterisks. ...
    (comp.lang.lisp)
  • Re: An ode to Erlang
    ... >> Why you think lightweight threads would be hard to ... >> implement this for Lisp is beyond my imagination. ... Erlang has processes. ... > and will most likely make access to global variables slower. ...
    (comp.lang.lisp)
  • Re: SETF and variable issues in Self Similar program.
    ... recursive calls to append, and the incremented global variables, lack ... calls to functions not standardized across lisp implementations, ... I played around with C and some other programming languages when I was ... gave them up, busy with other studies, and it wasn't until I found ...
    (comp.lang.lisp)