From: Rainer Joswig on
In article <878w8ks8jq.fsf(a)slack64.serverdot.org>,
xtd8865(a)gmail.com (.Martin.) wrote:

> I'm running SBCL in slime. I'm doing my first steps in common lisp.
> Everything is fine, but for some reason I got the errors:
>
>
>
> CL-USER> (setf x 1)
> ;
> ; caught WARNING:
> ; undefined variable: X
> ;
> ; compilation unit finished
> ; Undefined variable:
> ; X
> ; caught 1 WARNING condition
> 1
>
>
> Well, I know it's undefined - I'm trying to define it, aren't I?
> Am I missing something here?
>
> thank you


Variables in Common Lisp are introduced by constructs like DEFVAR, DEFPARAMETER, LET, DEFUN, LAMBDA, ... - but not SETQ or SETF.

If you use DEFVAR or DEFPARAMETER, they define a global variable and declare it to be 'special' (dynamic binding).
So it is usual style to write global variables introduced by DEFVAR or DEFPARAMETER as *x*.

--
http://lispm.dyndns.org/
From: .Martin. on
His kennyness <kentilton(a)gmail.com> writes:

> .Martin. wrote:
>> Barry Margolin <barmar(a)alum.mit.edu> writes:
>>
>>> In article <878w8ks8jq.fsf(a)slack64.serverdot.org>,
>>> xtd8865(a)gmail.com (.Martin.) wrote:
>>>
>>>> I'm running SBCL in slime. I'm doing my first steps in common lisp.
>>>> Everything is fine, but for some reason I got the errors:
>>>>
>>>>
>>>>
>>>> CL-USER> (setf x 1)
>>>> ;
>>>> ; caught WARNING:
>>>> ; undefined variable: X
>>>> ;
>>>> ; compilation unit finished
>>>> ; Undefined variable:
>>>> ; X
>>>> ; caught 1 WARNING condition
>>>> 1
>>>>
>>>>
>>>> Well, I know it's undefined - I'm trying to define it, aren't I?
>>>> Am I missing something here?
>>> No, you're trying to assign it. To define it, use DEFVAR or
>>> DEFPARAMETER.
>>
>> Thank you, it works. I though lips doesn't require defining symbols
>> beforehand. It seems I was wrong.
>>
>
> I see "warning" above. Where do you see "require"?
>
> I do not use SBCL/slime so I do not know if you were being stopped or
> warned, but if you were only being warned... right. Lisp will indeed
> warn you about undefined variables and also unused variables (they
> often come in pairs for the obvious reason). Useful indeed when they
> come in pairs. but yes, your observation is accurate: Lisp is not as
> wild and crazy as it is sometimes made out to be. Tho some Lisps
> are. An interpreted Lisp might fit that bill.
>
> kt

Thanks, acutally I didn't see it just warned me, the value has successfully been assigned.

--
regards

..Martin.
From: .Martin. on
Rupert Swarbrick <rswarbrick(a)gmail.com> writes:

> xtd8865(a)gmail.com (.Martin.) writes:
>>>
>>> No, you're trying to assign it. To define it, use DEFVAR or
>>> DEFPARAMETER.
>>
>> Thank you, it works. I though lips doesn't require defining symbols
>> beforehand. It seems I was wrong.
>
> Well, it'll actually work in the slime repl despite the warning
> (although that should probably be a sign you're doing something
> wrong...)
>
> I'm not absolutely sure, but I think the logic is that if you don't
> declare (not define) symbols explicitly, it's not clear what lisp should
> make happen here.
>
> (defun run-me ()
> (foo)
> (bar)
> (format t "~A~%" x))
>
> (defun foo ()
> (setf x 42)
> (format t "~A " x))
>
> (defun bar ()
> (format t "~A " x))
>
> What should be printed? 42 42 42? Why should lisp guess that you want
> the undeclared x to be a global variable? Anyway, that seems to be the
> logic to me.
>
> Rupert


Thanks for your explanation. It's just I didn't see any mention of
declaring variables in the beginners tutorials that I looked at
yesterday.
I assumed that in this respect it's like PHP.
--
regards

..Martin.
From: Captain Obvious on
M> Thank you, it works. I though lips doesn't require defining symbols
M> beforehand. It seems I was wrong.

I think the reason for this is that Common Lisp supports two kinds of
variables -- lexical and dynamic/special ones. (Well, there are also
"constant variables"...)

They obey to different rules: lexical variables are visible only within the
lexical scope of declaration (e.g. within the LET form -- (let ((x 5))
(print x)), invisible outside) and they can be captured by closures (in
other words, they have indefinite extent -- lexical bindings can live
forever if they are captured)
Special variables have indefinite scope -- that is, they can occur anywhere
and dynamic extent -- special variable binding exists only when function is
being called and is destroyed when you exit from the function.

So, it is important to know what variable you have -- program's logic
depends on it.

When you use defvar or defparameter, you declare a special variable this
way.
When you bind variable via LET, you either create a lexical
variable/binding, or you bind an existing special variable, if it was
declared as special previously.

But when you SETQ variable without creating it first, you have an undefined
behaviour, because this variable is neither lexical, nor special, and this
situation is not defined by the standard.

Common Lisp implementation are allowed to do whatever they think is
reasonable in this situation.
Some of them might automatically declare it as special for you -- but it is
very dangerous, because if it was a typo, it could silently break unrelated
pieces of code.

Others might create so-called "global lexical variable" -- variable which
can be bound lexically, but has some global value if it is not bound. This
kind of variables is not defined by the standard, so you cannot rely on it.
But they make sense, at least.

Another good reason to generate a warning is that it might be a typo.
Dynamic progamming languages suffer from situations when programs compile,
but break in runtime because of typos, so this kind of warnings is good.

From: Thomas A. Russ on
"Captain Obvious" <udodenko(a)users.sourceforge.net> writes:

> But when you SETQ variable without creating it first, you have an
> undefined behaviour, because this variable is neither lexical, nor
> special, and this situation is not defined by the standard.
>
> Common Lisp implementation are allowed to do whatever they think is
> reasonable in this situation.
> Some of them might automatically declare it as special for you -- but it
> is very dangerous, because if it was a typo, it could silently break
> unrelated pieces of code.
>
> Others might create so-called "global lexical variable" -- variable
> which can be bound lexically, but has some global value if it is not
> bound. This kind of variables is not defined by the standard, so you
> cannot rely on it. But they make sense, at least.

Well, there seem to be two main approaches that have been used.

One of them is to, in effect, declare the variable to be "locally"
special. In other words, the particular references where there is no
information are assumed to refer to a special variable. I think this is
at least similar to your lexical global in effect.

Other lisps (ARAIK only CMUCL and SBCL) will globally declaim the
variable as being special. This is essentially the effect you would get
from DEFVAR or DEFPARAMETER. It is a bit more intrusive, since it does
change the semantics of other lexical references to that variable.

--
Thomas A. Russ, USC/Information Sciences Institute