From: landspeedrecord
Subject: Passing Global Variables Urgh.
Date: 
Message-ID: <1188430108.062743.252690@o80g2000hse.googlegroups.com>
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)
      (setq x "orrgoaarghhh"))
TEST2

CM> (test2 *x*)
"orrgoaarghhh"

CM> *x*
"blargh"

My only guess is that the function "test2" gets passed a copy of the
global variable that is exists inside the function "test2".  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?

Now I could write "test2" so that it was:
(defun test2 ()
  (setq *x* "orrgoaarghhh"))
but that isn't the same as passing the global variable.

I just don't get it.  Urgh???

From: andrea
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <1188431344.449865.259490@d55g2000hsg.googlegroups.com>
On 30 Ago, 01:28, landspeedrecord <···············@gmail.com> 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)
>       (setq x "orrgoaarghhh"))
> TEST2
>
> CM> (test2 *x*)
> "orrgoaarghhh"
>
> CM> *x*
> "blargh"
>
> My only guess is that the function "test2" gets passed a copy of the
> global variable that is exists inside the function "test2".  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?
>
> Now I could write "test2" so that it was:
> (defun test2 ()
>   (setq *x* "orrgoaarghhh"))
> but that isn't the same as passing the global variable.
>
> I just don't get it.  Urgh???

Interesting, I don't know but I think it's because defvar creates
dynamic variables (from hyperspec)
dynamic variable n. a variable the binding for which is in the dynamic
environment. See special.
that maybe behaves in this strange way..
From: Geoff Wozniak
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <1188431539.873633.196720@r29g2000hsg.googlegroups.com>
On Aug 29, 7:28 pm, landspeedrecord <···············@gmail.com> wrote:
> First off... I know I am not supposed to use global variables in Lisp,
> however...
>

Why not?  They can be very handy.

> 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.
>

Variables are passed by values, not by reference.  Thus,

  (defun test2 (x)
    (setq x "orrgoaarghhh"))

sets the value of the parameter X, not what was passed to it.  If you
need to adjust parameters in the way you were expecting, you can use a
macro, but I doubt that's what you want to do.

One way to deal with this is to wrap the value in a cons cell, which
acts as a reference.  Similar effects can be achieved using structures
and classes.

CL-USER> (defparameter *x* (cons "yay!" nil))
*X*
CL-USER> (defun test (x) (setf (car x) "my value"))
TEST
CL-USER> (car *x*)
"yay!"
CL-USER> (test *x*)
"my value"
CL-USER> (car *x*)
"my value"

> My only guess is that the function "test2" gets passed a copy of the
> global variable that is exists inside the function "test2".  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?
>

In your example, you weren't setting the global(*) variable *X*, you
were setting the local parameter X.

(*) It's really called a special variable.
From: JK
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <fb51ir$s66$1@aioe.org>
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
From: Scott Burson
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <1188433074.207158.173140@q4g2000prc.googlegroups.com>
On Aug 29, 4:28 pm, landspeedrecord <···············@gmail.com> wrote:
> My only guess is that the function "test2" gets passed a copy of the
> global variable that is exists inside the function "test2".

Bingo.  Lisp, like most modern languages, is call-by-value.  The
`setq' within `test2' only modifies the value of `x'.

> 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?
>
> Now I could write "test2" so that it was:
> (defun test2 ()
>   (setq *x* "orrgoaarghhh"))
> but that isn't the same as passing the global variable.
>
> I just don't get it.  Urgh???

Lisp never passes variables by reference.  You must be coming from
some language (Fortran???) where call-by-reference is the default.

What you can do in Lisp (and Java, and ...) is to bind a global
variable to an object which can then be modified:

(defstruct x-holder
  thing)

(defvar *x* (make-x-holder :thing "blargh"))

(defun test2 (x)
  (setf (x-holder-thing x) "orrgoaarghhh"))

-- Scott
From: Rainer Joswig
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <joswig-640A9E.01454830082007@news-europe.giganews.com>
In article <························@o80g2000hse.googlegroups.com>,
 landspeedrecord <···············@gmail.com> 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)
>       (setq x "orrgoaarghhh"))

This sets the local variable X.

> TEST2
> 
> CM> (test2 *x*)
> "orrgoaarghhh"

Above is the same as calling

  (test2 "blargh")

> 
> CM> *x*
> "blargh"
> 
> My only guess is that the function "test2" gets passed a copy of the
> global variable

No, it gets passed a value, not a variable.

> that is exists inside the function "test2".  But isn't
> the whole point of Defvar & Defparameter to create a global variable
> that can be accessed from anywhere?

But you have to use their name if you want to access them.

>  If a copy of a global variable is
> always passed into functions what good is a global variable?
> 
> Now I could write "test2" so that it was:
> (defun test2 ()
>   (setq *x* "orrgoaarghhh"))
> but that isn't the same as passing the global variable.
> 
> I just don't get it.  Urgh???

Evaluation of a function call   (test2 *x*)

1) we see that TEST2 is a function.
2) a function call evaluates all the arguments 
  3) evaluation of *X*
  4) *X* is "blargh"
5) call TEST2 with "blargh" as the argument for X
   ...
...

So Lisp does not pass variables, but values.
From: Ralf Mattes
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <fb6co6$4hl$1@news01.versatel.de>
Just as an addition to the other posts (since noone cared
to sove your "problem"):



(defvar *x* "blub")

;;; We avoid 'setq' since we already get a symbol
;;; and don't need to quote it ...

(defun modify-it (symbol)
  (set symbol "newer blub"))

;;; Ok, we want to pass a _symbol_ so we better
;;; protect *x* from being evaluated before being 
;;; passed th modify-it - 'quote' to the rescue ...

(modify-it (quote *x*))

; => "newer blub"

;;; ... or, as a shorthand

(modify-it '*x*)

; => "newer blub"

;;; but beware!
(let ((honk 42))
  (warn "Value uf honk is ~A" honk)
  (modify-it 'honk)
  honk)

;;; Evaluate this expression twice and watch the 
;;; warning.
;;; strange, eh?
;;; Not really: or function doesn't "see" the 
;;; local bound honk and hence can't modify it. 
;;; It'll try to modify the globally visible honk -
;;; if honk doesn't exist asa global (special) variable
;;; all sorts of strange things might happen ...



HTH RalfD
From: John Thingstad
Subject: Re: Passing Global Variables Urgh.
Date: 
Message-ID: <op.txvcj5egpqzri1@pandora.upc.no>
P� Thu, 30 Aug 2007 01:28:28 +0200, skrev landspeedrecord  
<···············@gmail.com>:

>
> I just don't get it.  Urgh???
>

Others have explained dynamic variables.
Better to use a closure here

(let ((x "blargh"))
    (defun test2 ()
       (setf x "oorgoraah"))
    (defun get-x () x))

(get-x)
--> "blargh"
(test2)
--> "oorgoraah"
(get-x)
--> "oorgoraah"