Chapter 11. Advanced Types and Mechanisms

Table of Contents

11.1. Symbols
11.1.1. Undefined symbols
11.1.2. Uniqueness of Symbols
11.1.3. Properties
11.1.4. Predefined Symbols
11.2. Evaluation
11.2.1. Evaluation of a Symbol
11.2.2. Evaluation of a List
11.2.3. Evaluation to Itself
11.3. Literal Syntax and Evaluation
11.3.1. Literal Expressions
11.3.2. Deferring Expression Evaluation
11.3.3. Literal Function Arguments
11.3.4. Partially Evaluated Literal
11.3.5. Constructing Variable Names at Run-time
11.3.6. Literal Array Syntax

11.1. Symbols

We introduced symbols in the Symbols and Values section at the beginning of this Guide. Recall that a symbol is a unique word or name within the system, and that references to a particular symbol will be to the exact same Gamma object, regardless of how that reference was obtained. Symbols can be used as variables, as they may have a value that can be queried through evaluation. The value of a symbol can change depending on the current execution scope.

A symbol may contain any character, though it is necessary to escape some characters using a backslash (\) when writing them. The normal character set for symbols consists of the following:

    The lowercase letters (a-z)

    The uppercase letters (A-Z)

    The digits (0-9)

    The underscore (_)

A symbol is created by a call to symbol, or by reading any legal string of characters which forms a symbol.

11.1.1. Undefined symbols

In Gamma a variable must be assigned a value. A variable does not exist until a value is assigned to it. Once defined, both the value and type of a variable can be changed, effectively re-defining the variable. A variable which is used but has never been assigned a value will cause an error:

Gamma> 3 + k;
Symbol is undefined: k
debug 1>

The undefined_p function can be used to test if a variable is defined, as follows:

Gamma> undefined_p (a);
t
Gamma> a = 5;
5
Gamma> undefined_p (a);
nil
	  

11.1.2. Uniqueness of Symbols

The uniqueness of symbols in the system provides an interesting way to perform the equivalent of the C language enumerated type, in case you want a list of constant values representing different things. In Gamma, when two symbols are tested for equality, the comparison is first done on the symbol reference itself, not the value associated with the symbol. This is because the Gamma == operator is mapped to the Lisp equal function, which determines equality first with the eq function. The Lisp eq function tests for equality of the reference, and only if this has failed will the equal function perform an equality test on the value of the references. Also in Gamma, a symbol can be defined without assigning a value.

When the Gamma engine reads a literal symbol (see Literal Syntax and Evaluation in this chapter), as illustrated in the example below, it determines that the reference is in fact a symbol. If the symbol does not exist, Gamma creates the it with a value of _undefined_.

Gamma> x = #yes;
yes
Gamma> yes;
Symbol is undefined: yes
debug 1>
	  

Therefore, it is valid in Gamma to make comparisons for equality between symbols whose values are not defined. Such comparisons between symbols are actually more efficient than comparing the values of two symbols. This leads to the following example. Here Gamma uses the equivalent of an enumerated type, but it is more efficient than assigning actual values to the constants, since the test is for the symbol reference only.

Gamma> function my_state (x)
{
if (x==#on) 
    princ ("I am on.\n"); 
else if (x==#off)
    princ ("I am off.\n");
else if (x==#unstable)
    princ ("I am not stable.\n");
else
    princ ("I don't know.\n");
}
(defun .......)
Gamma> a = #on;
on
Gamma> my_state (a);
I am on.
t
Gamma> my_state (#off);
I am off.
t
	  

Notice that the enumerated set (on, off, unstable) was not created as variables with assigned values (1, 2, 3,...) but used directly, leading to a more efficient and cleaner implementation.

11.1.3. Properties

Symbols can be assigned properties, using the setprop function. Each assigned property is a name/value pair, which is globally defined for the symbol, regardless of the current scope and value. These properties can be accessed using the getprop function.

11.1.4. Predefined Symbols

There are some symbols, such as _undefined_ mentioned above, whose values are predefined in Gamma. For the complete listing of symbols that are predefined in Gamma see section Predefined Symbols in the Reference Manual.