Is the X in (LET ((x ...)) entirely a flash character?

Or in other words: is it possible for a variable in CL to not be (part of) a symbol?

I think I may have a deep misconception regarding variables in CL.

I always thought that CL has no variables, only symbols and symbols have (among other properties) a name and a value cell (which is a variable).

And when someone said that "the variable x

has a value of 42" I thought it was short for "the value cell of the character named x

stores the value 42".

But this is probably not true.

When i type

> (let ((a 42))
       (type-of 'a))
SYMBOL
; caught STYLE-WARNING:
;   The variable A is defined but never used.

      

is the lexical variable a

in this example a fully composed character whose value cell is set to 42?

As the warning The variable A is defined but never used

indicates otherwise and it seems that the lexical variable does not match the character a

in the following form (type-of 'a)

.

+3


source to share


3 answers


Common Lisp has two types of data that are of particular importance for evaluation:

  • cons cells / lists -> used in Lisp source code, Lisp forms lists
  • symbols → are used as names for various purposes

If you want to use them as data in your Lisp code, you must quote them.

Both are used in the Lisp source code, but after compiling the code, they may disappear.

Variables are written as symbols in the source code. But in compiled code they can disappear - when they are lexical variables.

An example of using SBCL:

file with

(defun test (foo)
  (+ foo foo))

      



Now we do:

CL-USER> (proclaim '(optimize (debug 0)))  ; the compiler saves no debug info
; No value
CL-USER> (compile-file "/tmp/test.lisp")
; compiling file "/private/tmp/test.lisp" (written 23 MAY 2017 09:06:51 PM):
; compiling (DEFUN TEST ...)

; /tmp/test.fasl written
; compilation finished in 0:00:00.013
#P"/private/tmp/test.fasl"
NIL
NIL
CL-USER> (find-symbol "FOO")
FOO
:INTERNAL

      

The compiler read the source code and created a compiled FASL file. We can see that the symbol is FOO

now in the current package. FOO

names a variable in our source code.

Now close SBCL and restart it.

Download the machine code:

CL-USER> (load "/tmp/test")
T
CL-USER> (find-symbol "FOO")
NIL
NIL

      

There is no FOO

more symbol . It is also not possible to get the lexical value of a variable FOO

using a symbol FOO

. There is no collation (such as any explicit lexical environment) from characters to lexical values.

+5


source


The value cell is used for dynamic (AKA "special") variables, not lexical variables. Lexical variables are symbols in the source code, but they have no runtime relationship to a symbol (other than internal use by the debugger).

So if you wrote:



(let ((a 42))
  (declare (special a))
  (print (symbol-value 'a)))

      

it will work because the declaration makes it a dynamic variable and then you can access the value in the function cell.

+5


source


You do not check the type of the bound variable a

or its value, other than the constant letter character, which has the same name as the variable in your form let

:

(let ((a 42))
  (type-of 'literal-symbol))
; ==> symbol (since 'literal-symbol evaluates to a symbol, just like 'a does)

      

To check the type of the binding value a

, you do it without literal quotation:

(let ((a 42))
  (type-of a))
; ==> (integer 0 281474976710655)

      

Here you are actually checking the value type of let let bound and an integer. Surprised that it 42

is a number and not a symbol?

(let ((a 10) (b 'a))
  (list a b))
; ==> (10 a)

      

The variable a

and the quoted literal 'a

do not match. They just look the same when displayed, but 'a

they are data and they a

are code. In CL, the compiler can use lists and symbols internally, but what happens when its execution is completely implementation-specific, and in most implementations they allocate the stack when they can, and the code that evaluates the stack-allocated variable is replaced with something that pops the value at the index from the stack. CL has a feature disassemble

, and if you inspect the SBCL output from something, you can see that it looks more like the C compiler output than the original lisp source.

+2


source







All Articles