This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

(setf a-new-symbol 'value) at the top level

5 posts · 6166 views

I did this inadvertently, but I was surprised by the results, and I was wondering if someone could help explain what I'm seeing
* (setf westvleteren 12)
;     (SETF WESTVLETEREN 12)
; ==>
;   (SETQ WESTVLETEREN 12)
; 
; caught WARNING:
;   undefined variable: WESTVLETEREN
; 
; compilation unit finished
;   Undefined variable:
;     WESTVLETEREN
;   caught 1 WARNING condition
=> 12
I was not surprised by the warnings, but I was surprised by the fact that it returned a value. So I had a look at what the symbol now contained:
* westvleteren
=> 12
It got my value. Weird. But what does describe say?
* (describe 'westvleteren)
COMMON-LISP-USER::WESTVLETEREN
  [symbol]

WESTVLETEREN names an undefined variable:
  Value: 12
; No value

What does "undefined variable" mean, if it has a value? Is this behaviour defined, or is it implementation-dependant?


$ sbcl --version
SBCL 1.0.40.0.debian
~garethw

Re: (setf a-new-symbol 'value) at the top level

Some lisps allow this behaviour without error or warning (and users of said lisps tend to be snooty about the fact that sbcl doesn't, e.g. Doug Hoyte in LOL).

Always use defvar for portability

Re: (setf a-new-symbol 'value) at the top level

Setting a variable at the top level sets the global value of the variable without proclaiming it special. This is useful because if you use a variable x at top level and then enter a defun that also uses a variable named x then x might be mistakenly interpreted as a global variable inside the function. That way you may use any variable name inside the repl without the fear of breaking your program.
garethw wrote:What does "undefined variable" mean, if it has a value?
In Lisp you don't need to declare or define variables. But if you bind a variable like in (let ((x 1)) ...) then the interpreter/compiler has to determine whether x is proclaimed special so it can decide whether x is to be bound lexicaly or dynamicaly. It does this by looking up the symbol in a database that contains all the proclamations (actually, this database is called the binding.) What SBCL wants to tell you is that the binding doesn't contain any proclamations for that variable.
garethw wrote:Is this behaviour defined, or is it implementation-dependant?
It's defined by the ANSI standard.

Re: (setf a-new-symbol 'value) at the top level

Konfusius wrote:Setting a variable at the top level sets the global value of the variable without proclaiming it special.
Yes, it does on some implementations, but conforming programs may not rely on this behavior.

In Lisp you don't need to declare or define variables. But if you bind a variable like in (let ((x 1)) ...) then the interpreter/compiler has to determine whether x is proclaimed special [...]
Actually, lexical binding is the default for LET, unless the variable is declared SPECIAL. Top-level variables are a different beast, though---ANSI CL does not specify a way of creating lexical globals. DEFVAR and DEFPARAMETER both globally declare the variables they define SPECIAL.

On the other hand, there are portable ways of defining something that behaves as a global lexical. They generally rely on DEFINE-SYMBOL-MACRO. (Google DEFLEX or DEFLEXICAL; also see the LEXICAL-CONTEXTS package in the MISC-EXTENSIONS library available via Quicklisp.)

garethw wrote:Is this behaviour defined, or is it implementation-dependant?
It's defined by the ANSI standard.
No; setting undeclared variables has undefined consequences. Of course, there is nothing wrong with relying on implementation-specifics when interacting with the REPL. Just be aware that SETQing an undeclared variable may do all sorts of things in general, like implicitly doing a DEFVAR (declaring the variable SPECIAL and thereby potentially causing hard-to-trace problems), or signalling an error.

Re: (setf a-new-symbol 'value) at the top level

A big thanks for all your insights.
~garethw