From: Javier F.
Subject: beginner confused
Date: 
Message-ID: <3368D9A5.4953@kender.es>
Hello:

I'm a lisp beginner and i got an elemental question, i guess
it's something trivial for someone with a little of experience
programming in lisp but i got no expertise.

Well, i got the next function:

(defun init_stack (p)
	(setf p nil))

and when i invoke the function in this way:

	(init_stak st)

being st a no declarated variable an error occurs:
	"unbound variable st"

i would like to know if there's any way to make it without
declare the variable st. I wanna say to make the declaration
inside the function. If anybody knows it (i guess everybody'll
know it) please send me an e-mail explaining it. I don't know
but maybe it could be a nosense question cos maybe it's not
interesting do that (i'm very confused at this point), if so
tell me it.

Thank you very much.



Javi

From: Bill House
Subject: Re: beginner confused
Date: 
Message-ID: <01bc568b$3c8abf20$03d3c9d0@wjh_dell_133.dazsi.com>
Javier F. <········@kender.es> wrote in article <·············@kender.es>...
>
>[snip examples]
>
> 
> i would like to know if there's any way to make it without
> declare the variable st. I wanna say to make the declaration
> inside the function. If anybody knows it (i guess everybody'll
> know it) please send me an e-mail explaining it. I don't know
> but maybe it could be a nosense question cos maybe it's not
> interesting do that (i'm very confused at this point), if so
> tell me it.
> 
Well, to pass a variable you have to have a variable -- just attempting to pass a
random symbol is indeed an error. Where is this st supposed to come from? If you want
to create it in the init_stak function, then why pass it?

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Kent M Pitman
Subject: Re: beginner confused
Date: 
Message-ID: <sfw7mhio5ls.fsf@world.std.com>
In article <·············@kender.es> "Javier F." <········@kender.es> writes:

> I'm a lisp beginner [...]

Hola.  Bienvenidos al mundo de Lisp!

> i got the next function:
>
>   (defun init_stack (p) (setf p nil))
>
> and when i invoke the function in this way:
>
>	   (init_stak st)
>
>   being st a no declarated variable an error occurs:
>	   "unbound variable st"

I think you are assuming that when you call init_stak it will set the
storage in ST to NIL, but it will not.

Lisp is not a call-by-reference language.  Some people call Lisp a
call-by-value language; however, it differs from most call-by-value
languages in that it passes a pointer to the value, not a copy of
the value.  But the important point is that it doesn't pass a pointer
to the storage location from which the value came.

When you invoke any function in Lisp, the value of each argument is
first obtained and then a pointer to that value (not a pointer to the
storage location from which it might have come) is passed to the
function.  So since ST has no value, you get an error when trying to
find out the arguments to INIT_STAK and you don't even get as far as
calling the function.

This problem would not be repaired by initializing ST.  You would 
find that

 (SETQ ST NIL)
 (INIT_STACK ST)


would not signal an error, but it would also not be doing what you wanted.
To see the problem, try

 (SETQ ST 'FOO)
 (INIT_STACK ST)
 ST => FOO

That is, the assignment in INIT_STAK affects only the local variable P, not
the location, ST, from which caller's argument, FOO, was obtained.

One way to do what you want is to use a macro.  A macro is a source-to-source
rewrite program.  So if you wrote:

 (defmacro init_stak (p) `(setf ,p nil))

then any time you used

 (init_stak st)

it would be as if you had written literally

 (setf st nil)

You can test this by doing:

 (macroexpand-1 '(init_stack st)) => (SETF ST NIL)

Another way to do this is to make a STACK be not a simple list, but a
structure that can be modified.  For example:

 (defstruct stack 
   (storage nil))

Then you can do

 (defun push-stack (element stack)
   (push element (stack-storage stack)))
 (defun pop-stack (stack)
   (pop (stack-storage stack)))
 (defun init-stack (stack)
   (setf (stack-storage stack) nil))

In this case, if you do

 (setq st (make-stack))

then st will be the same object no matter whether it is empty or has
many elements, and you can use init-stack on that object because it won't
be the variable ST you are modifying, but rather it will be the object
which ST holds that you are modifying.  So later when someone else looks
at ST, they will see that it has been modified.  (This wouldn't be true
in languages which are call-by-value that copy function arguments because
the side-effect would not propagate back to the calling function.)

Ojala' que esta respuesta sera' suficiente.  Si no, me puede mandar e-mail
y tratare' de explicar ma's.
 --Kent Pitman
   ···@harlequin.com