Automatic backups
Chapter 4 Evaluating expressions
4.3. Symbols and assignment
Let’s see what happens when we type only the sign +, not including it in a list:
_$ +
#<SUBR @00000000341d2ba8 +>
_$
We obtain the value represented by the + symbol, which is none other than the internal identifier of one of the language’s own subroutines.
The concept of symbol is very important in LISP. A symbol represents
something. Numbers represent themselves. They cannot represent anything else.
Thus the name of a LISP symbol can include numbers, but cannot be composed only by numbers. It must always include letters or some other non-numeric character. The following are valid symbol names: aa5 xyz *5*. For the same reason a symbol name will never include quotes4.
The symbols colored in blue have a meaning which is assigned by the system.
The other possible symbols will not have a value until the user assigns it. If we type in the Console the symbol names given above we obtain the following result:
We see how pressing ENTER after typing more than one expression on the same line of the Console, Visual LISP evaluates each of them in the order they were typed and then returns their results in successive lines. It has been nil in all cases. The LISP symbol nil is equivalent to nothing.
The function we use to assign a specific value to a symbol is setq. Thus the expression (setq a 100) will assign the integer 100 as the value of the symbol
a. Once we have done this, evaluating a will return 100.
If we examine the allocation process using setq we observe that the evaluation rule explained above is not followed here. Of the two arguments passed to setq
the first one, the symbol a was not evaluated5. In fact setq is the combination of two other functions: set and quote. The quote function returns its argument without evaluating it.
_$ (quote a) A
_$ a 100 _$
We see that (quote a) returns A in upper case. This reveals another LISP
feature: internally all the symbol names are converted to uppercase. Therefore it is indifferent to use upper or lowercase characters in them. the evaluation of a
outside the quote still returns 100.
The set function, like setq, assigns the value of its second argument to the first one, but in this case the first argument is always evaluated. This is avoided by using quote. The following expressions have the same effect:
_$ (setq a5 "ghi")
"ghi"
_$ a5
"ghi"
_$ (set (quote a5) "mno")
"mno"
_$ a5
"mno"
_$
Setq as we can see in the example above, is an abbreviation of (set (quote
that saves code typing. Also quote can be abbreviated by using the apostrophe (') character:
The apostrophe character is colored brown, which avoids confusion with similar characters such as accents. As seen from their results, the above two previous expressions are identical.
Set has a rather exceptional use when you want to assign a value to a symbol that is represented by another or resulting from the evaluation of a particular expression:
_$ c 250 _$
Note the use of quote in the expression (setq b 'c). Without quote we would be assigning b the value nil. The integer 250 is assigned not to b, but to
c which is the value represented by the symbol b. Two further aspects to consider:
Setq can receive any number of pairs of arguments <symbol><value>. Each <symbol> argument will be assigned the <value> argument that follows, processing the pairs as usual, from left to right.
Symbols representing numerical values can be used in an expression instead of the represented numbers.
_$ (setq a 20 b 10)
Lists are LISP’s most characteristic data type . They are expressed as zero or more elements enclosed in parentheses. The elements of a list can correspond to any data type, including other lists. We have seen that function calls take the form of lists. When we use a list as data we must precede it with quote to prevent the system from confusing it with a function call.
The following expressions are lists. The first one composed exclusively by numbers, the second one by symbols and the third one mixing different LISP objects such as the number 3, the symbol three, the string "abc" and symbols d (3 THREE "abc" D E) _$
Observe two things:
the symbols are converted to uppercase to be printed by the system, but not
so the string;
a single initial quote protects the entire list from evaluation.
If we wish to build a list from expressions that should be evaluated we cannot use quote. In that case we should employ the list function which returns a list including the result of evaluating its arguments:
_$ (setq a 20 b 10 c 5) 5
_$ (list c b (+ b c) a) (5 10 15 20)
_$
The fact that LISP programs are expressed as lists requires a very clear understanding of the relationship between expressions and lists. If a list is preceded by quote, Its evaluation returns that same list, otherwise it is considered an expression to be evaluated and returns its result:
_$ (list '(+ 2 1) (+ 2 1)) ((+ 2 1) 3)
_$
In the previous example the first argument is preceded by quote, therefore a list is returned. The second argument is taken as an expression to evaluate and
returns a number. If a list is not preceded by quote and its first term is not a function, its evaluation will return an error:
_$ (3 three "abc" d e)
; error: bad function: 3 _$
Before we said that a list may contain no elements. The empty list is equivalent to the nil symbol. It Is expressed by an opening parenthesis followed by a closing one.
Here the result is always the same, regardless of whether or not the empty list is preceded by quote since the symbol nil is representing itself.