Page 1 of 1

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

Posted: Sun Aug 05, 2012 2:10 pm
by garethw
I did this inadvertently, but I was surprised by the results, and I was wondering if someone could help explain what I'm seeing

Code: Select all

* (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:

Code: Select all

* westvleteren
=> 12
It got my value. Weird. But what does describe say?

Code: Select all

* (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

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

Posted: Mon Aug 06, 2012 6:05 am
by pjstirling
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

Posted: Mon Aug 06, 2012 6:43 am
by Konfusius
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

Posted: Tue Aug 07, 2012 2:45 am
by Kompottkin
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

Posted: Tue Aug 07, 2012 11:33 am
by garethw
A big thanks for all your insights.