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.