In terms of scope? Actual implementation in memory? The syntax? For eg, if (let a 1) Is 'a' a variable or a symbol?
相关问题
- Generating powerset in one function, no explicit r
- Drakma and Dexador both fails at USocket call whil
- Relation between Function1 and Reader Monad
- scala passing function with underscore produces a
- Combining n vectors into one vector of n-tuples
相关文章
- Is there something like the threading macro from C
- Learning F#: What books using other programming la
- Creating a list of functions using a loop in R
- Does learning one Lisp help in learning the other?
- Common Lisp: Why does my tail-recursive function c
- What is the definition of “natural recursion”?
- How do I write a macro-defining macro in common li
- How can I unintern a qualified method?
Symbol and variable are 2 different things. Like in mathematic symbol is a value. And variable have the same meaning than in mathematic.
But your confusion came from the fact that symbol are the meta representation of a variable.
That is if you do
You just define a variable a. Incidentally the way common lisp store it is throw the structure of a symbol.
In common lips symbol is a structure withe different property. Each one can be access with function like
symbol-name
,symbol-function
...In the case of variable you can access his value via s
symbol-value
This is not the common case of getting the value of a.
Note that symbols are self evaluating that mean that if you ask a symbol you get the symbol not the
symbol-value
Jörg's answer points in the right direction. Let me add a bit to it.
I'll talk about Lisps that are similar to Common Lisp.
Symbols as a data structure
A symbol is a real data structure in Lisp. You can create symbols, you can use symbols, you can store symbols, you can pass symbols around and symbols can be part of larger data structures, for example lists of symbols. A symbol has a name, can have a value and can have a function value.
So you can take a symbol and set its value.
Usually one would write
(setq foo 42)
, or(set 'foo 42)
or(setf foo 42)
.Symbols in code denoting variables
But!
or
In both forms above in the source code there are symbols and
a
is written like a symbol and using the functionREAD
to read that source returns a symbola
in some list. But thesetq
operation does NOT set the symbol value ofa
to42
. Here theLET
and theDEFUN
introduce a VARIABLEa
that we write with a symbol. Thus theSETQ
operation then sets the variable value to42
.Lexical binding
So, if we look at:
We introduce a global variable
FOO
.In bar the first
SETQ
sets the symbol value of the global variableFOO
. The secondSETQ
sets the local variableBAZ
to3
. In both case we use the sameSETQ
and we write the variable as a symbol, but in the first case theFOO
donates a global variable and those store values in the symbol value. In the second caseBAZ
denotes a local variable and how the value gets stored, we don't know. All we can do is to access the variable to get its value. In Common Lisp there is no way to take a symbolBAZ
and get the local variable value. We don't have access to the local variable bindings and their values using symbols. That's a part of how lexical binding of local variables work in Common Lisp.This leads for example to the observation, that in compiled code with no debugging information recorded, the symbol
BAZ
is gone. It can be a register in your processor or implemented some other way. The symbolFOO
is still there, because we use it as a global variable.Various uses of symbols
A symbol is a data type, a data structure in Lisp.
A variable is a conceptual thing. Global variables are based on symbols. Local lexical variables not.
In source code we write all kinds of names for functions, classes and variables using symbols.
There is some conceptual overlap:
In the above SOURCE code,
defun
,foo
,bar
,setq
andbaz
are all symbols.DEFUN
is a symbol providing a macro.FOO
is a symbol providing a function.SETQ
is a symbol providing a special operator.BAZ
is a symbol used as data. Thus the quote beforeBAZ
.BAR
is a variable. In compiled code its symbol is no longer needed.A symbol is a Lisp data object. A Lisp "form" means a Lisp object that is intended to be evaluated. When a symbol itself is used as a Lisp form, i.e. when you evaluate a symbol, the result is a value that is associated with that symbol. The way values are associated with symbols is a deep part of the Lisp langauge. Whether the symbol has been declared to be "special" or not greatly changes the way evaluation works.
Lexical values are denoted by symbols, but you can't manipulate those symbols as objects yourself. In my opinion, explaining anything in Lisp in terms of "pointers" or "locations" is not the best way.
Quoting from the Common Lisp HyperSpec:
Explanation time.
What Lisp calls symbols is fairly close to what many languages call variables. In a first approximation, symbols have values; when you evaluate the expression
x
, the value of the expression is the value of the symbolx
; when you write(setq x 3)
, you assign a new value tox
. In Lisp terminology,(setq x 3)
binds the value 3 to the symbolx
.A feature of Lisp that most languages don't have is that symbols are ordinary objects (symbols are first-class objects, in programming language terminology). When you write
(setq x y)
, the value ofx
becomes whatever the value ofy
was at the time of the assignment. But you can write(setq x 'y)
, in which case the value ofx
is the symboly
.Conceptually speaking, there is an environment which is an association table from symbols to values. Evaluating a symbol means looking it up in the current environment. (Environments are first-class objects too, but this is beyond the scope of this answer.) A binding refers to a particular entry in an environment. However, there's an additional complication.
Most Lisp dialects have multiple namespaces, at least a namespace of variables and a namespace of functions. An environment can in fact contain multiple entries for one symbol, one entry for each namespace. A variable, strictly speaking, is an entry in an environment in the namespace of variables. In everyday Lisp terminology, a symbol is often referred to as a variable when its binding as a variable is what you're interested in.
For example, in
(setq a 1)
or(let ((a 1)) ...)
,a
is a symbol. But since the constructs act on the variable binding for the symbola
, it's common to refer toa
as a variable in this context.On the other hand, in
(defun a (...) ...)
or(flet ((a (x) ...)) ...)
,a
is a also symbol, but these constructs act on its function binding, soa
would not be considered a variable.In most cases, when a symbol appears unquoted in an expression, it is evaluated by looking up its variable binding. The main exception is that in a function call
(foo arg1 arg2 ...)
, the function binding forfoo
is used. The value of a quoted symbol'x
or(quote x)
is itself, as with any quoted expression. Of course, there are plenty of special forms where you don't need to quote a symbol, includingsetq
,let
,flet
,defun
, etc.Lisp uses environments which are similar to maps (key -> value) but with extra built-in mechanisms for chaining environments and controlling bindings.
Now, symbols are pretty much, keys (except special form symbols), and point to a value,
ie function, integer, list, etc.
Since Common Lisp gives you a way to alter the values, i.e. with
setq
, symbols in some contexts(your example) are also variables.
A symbol is a name for a thing. A variable is a mutable pointer to a mutable storage location.
In the code snippet you showed, both
let
anda
are symbols. Within the scope of thelet
block, the symbola
denotes a variable which is currently bound to the value1
.But the name of the thing is not the thing itself. The symbol
a
is not a variable. It is a name for a variable. But only in this specific context. In a different context, the namea
can refer to a completely different thing.Example: the symbol
jaguar
may, depending on context, denote