[Openmcl-devel] Compiler warnings

Gary Byers gb at clozure.com
Fri Oct 16 12:56:40 PDT 2009



On Fri, 16 Oct 2009, David L. Rager wrote:

> Hi Taoufik,
>
> You need to define x to avoid those warnings.
>
> (defvar *x* '(a b c))
>
> Note that I'm fairly sure that defvar only sets a variable's value
> upon initialization.  Any subsequent calls to define the same variable
> are effectively no-ops.

See also DEFPARAMETER.

>
> IIRC, I think that if you're in a multi-threaded environment, not
> defining a variable causes the setf's to be thread-local.

A (special) binding is basically a mapping between a special variable
name (a symbol) and a value.  One trivial and traditional way to
establish such a binding is to reserve a word in the symbol for
its global special value; this word is sometimes referred to as the
symbol's "value cell", and that binding is sometimes called a "static
binding".

Things like LET/LET*/LAMBDA can establish new dynamic (and
thread-local) bindings for special variables.

SETF/SETQ of a special variable always assign to the current thread's
current binding of that special variable.  The current binding is either
the most recently established (by LET/LET*/LAMBDA ...) dynamic binding
or the global static binding if the thread has no dynamic binding.

Things like DEFVAR are usually used at toplevel (in the REPL or in a
file), and so any assignment that they do usually affects the global,
static binding.

Back to the original poster's question: in something like:

? (setq x '(1 2 3))

what exactly is X ?  Let's assume that:

1) it's not something proclaimed (via DEFCONSTANT) to be the name of
    a constant
2) it's not something proclaimed (via DEFVAR, DEFPARAMETER, or other
    means) to be the name of a SPECIAL (dynamic) variable.
3) it's not a lexical variable established by a surrounding LET/LET*/
    LAMBDA/... form that establishes lexical bindings.

In portable CL, those are the only well-defined possibilities.  In
practice (and in most? all? implementations), there are at least two
other possibilities:

4) it's a reference/assignment to the "static binding" of X, e.g., the
    "value cell of X", which is likely to be a meaningful concept.
5) it's a typographical error or a symptom of one; it can be treated
    something like case (4), but is anomalous enough to be worth warning
    about.

When compiling a file, it's desirable to treat references/assignments
to "undeclared free variables" (variables that don't fit into one of
the first 3 cases above) as being deserving of warnings.  Some people
habitually introduce "undeclared free variables" when typing
expressions to the REPL; some forms typed into the REPL in CCL are
handled by very simple evaluator (which generally doesn't try to warn
about this sort of thing); other forms are "evaluated" by compiling
them and funcalling the resulting function, and the compiler generally
does warn in this case.

Some people have requested that warnings like this be suppressed in the
REPL.  I used to be more sympathetic to that than I am now (for whatever
reason);  I think that I've convinced myself that the small extra effort
involved in saying something like:

? (defvar *x* '(1 2 3))

rather than

? (setq x '(1 2 3))

even for something trival done in the REPL.  (Things that start out trivial
sometimes get at least a bit more complicated, actual typos get introduced,
and it starts to get hard to remember what "the convenience of not having
to use DEFVAR when you more-or-less meant to" was all about.)

I guess that I'd agree that things should be consistent (and the simple
evaluator should warn in the same cases that the compiler does), but I
find it harder to agree that warnings should be suppressed: case (4) above
isn't all that well-defined and to the extent that pretending that it is
is a habit, that habit's breakable.

>
> David
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list