Up | Next | Prev | PrevTail | Tail |
In contrast to many programming languages, type declarations are not needed in PSL. Data objects contain information about their type. Some functions, like equal, are ”generic” in that the result they return depends on the types of the arguments.
For the purposes of input and output, an appropriate notation is used for each type of data object used in PSL. For example, double quotes are used to delimit the characters of a string. For a full discussion on syntax see Chapter 12.
The basic data types supported in PSL and a brief indication of their representations are described below.
The integers are also called ”fixed” numbers. The magnitude of integers is essentially unrestricted if the ”big number” module, zbig, is loaded. The notation for integers is a sequence of digits in an appropriate radix (radix 10 is the default, which can be overridden by a radi prefix, such as 2#, 8#, 16# etc). There are three internal representations of integers, chosen to suit the implementation:
A signed number fitting into info. Inums do not require dynamic storage and are represented in the same form as machine integers.
A full-word signed integer, allocated in the heap.
A signed integer of arbitrary precision, allocated as a vector of system integers. These integers may be not integers for PSL, because they do not fit into info. Beware. Bignums are currently not installed by default, to use them load the ZBIG module.
A floating point number, allocated in the heap. The precision of floats is determined solely by the implementation. Usually, the floating numbers are equivalent to system ’doubles’, (64 bits). The notation for a float is a sequence of digits with the addition of a single floating point ( . ) and an optional exponent (E <integer>). (No spaces may occur between the point and the digits). Radix 10 is used for representing the mantissa and the exponent of floating point numbers.
An identifier (or id) is an item whose info field points to a five-item structure containing the print name, property cell, value cell, function cell, and package cell. This structure is contained in the id space. The notation for an id is its print name, an alphanumeric character sequence. One always refers to a particular id by giving its print name. When presented with an appropriate print name, the PSL reader will find a unique id to associate with it. See Chapters 4 and 12 for more information on ids and their syntax. The ids t and nil are considered special in that it is not possible for the user to redefine their value cells.
A primitive two-item structure which has a left and right part. A notation called dot-notation is used, with the form: (<left-part> . <right-part>). The <left-part> is known as the car portion and the <right-part> as the cdr portion. The parts may be any item. (Spaces are used to resolve ambiguity with floats; see Chapter 12).
A primitive uniform structure of items; an integer index is used to access random values in the structure. The individual elements of a vector may be any item. Access to vectors is by means of functions for indexing, sub-vector extraction and concatenation, defined in Section 7.1. In the notation for vectors, the elements of a vector are surrounded by square brackets: [item-0 item-1 ... item-n].
A packed vector (or byte vector) of characters; the elements are small integers representing the ASCII codes for the characters (usually inums). The elements may be accessed by indexing, substring and concatenation functions, defined in Chapter 6. String notation consists of a series of characters enclosed in double quotes, as in ”THIS IS A STRING”. A quote is included by doubling it, as in ”HE SAID, ””LISP”””. A string may be input across the end of a line but a warning will be given unless the switch eolinstringok is non-nil (see Chapter 12).
A vector of machine-sized words, used to implement such things as fixnums, bignums, etc. The elements are not considered to be items, and are not examined by the garbage collector.
A vector of bytes. Internally a byte-vector is the same as a string, but it is printed differently as a vector of integers instead of characters.
This item is used to refer to the entry point of compiled functions (exprs, fexprs, macros, etc.), permitting compiled functions to be renamed, passed around anonymously, etc. New code-pointers are created by the loader (lap, fasl) and associated functions. They can be printed; the printing function prints the number of arguments expected as well as the entry point. The value appears in the convention of the implementation (e.g. #<Code A N>, where A is the number of arguments and N is the entry point).
Certain functional arguments can be any of a number of types. For convenience, we give these commonly used sets a name. We refer to these sets as ”classes” of primitive data types. In addition to the types described above and the names for classes of types given below, we use the following conventions in the manual. {XXX, YYY} indicates that either data type XXX or data type YYY will do. {XXX}-{YYY} indicates that any object of type XXX can be used except those of type YYY; in this case, YYY is a subset of XXX. For example, {integer, float} indicates that either an integer or a float is acceptable; {any}-{vector} means any type except a vector.
Any of the types given above. S-expression is another term for any. All PSL entities have some value unless an error occurs during evaluation.
The class any-pair.
The class of global variables t, nil, or their respective values, t, nil. (See Section 4.6).
Integers in the range of 0 to 255 without 128 representing ASCII character codes. These are distinct from single-character ids.
The class of integer, float, string, vector, code-pointer. A constant evaluates to itself (see the definition of eval in Chapter 11).
Any value in the system. Anything that is not nil has the boolean interpretation t.
The set of ids (expr, fexpr, macro, and nexpr), which represent definable function types. The ftype is only an attribute of identifiers, and is not associated with either executable code code-pointers or lambda expressions.
A small integer representing an io channel (see Chapter 12 for a complete discussion of io-channels).
The class of integer, float.
Any kind of vector; i.e. a string, vector, w-vector, or word.
An implementation-dependent value returned by some low-level functions; i.e. the user should not depend on this value.
A notational convenience used to indicate control functions that do not return directly to the calling point, and hence do not return a value (for example, see the function go in Chapter 8).
Structures are entities created using pairs. Lists are structures very commonly required as parameters to functions. If a list of homogeneous entities is required by a function, this class is denoted by xxx-list, in which xxx is the name of a class of primitives or structures. Thus a list of ids is an id-list, a list of integers is an integer-list, and so on.
A list is recursively defined as nil or the pair (any . list). A special notation called list-notation is used to represent lists. List-notation eliminates the extra parentheses and dots required by dot-notation, as illustrated below. List-notation and dot-notation may be mixed, as shown in the second example.
Note: () is an alternate input representation of nil.
An a-list, or association list, is a list in which each element is a pair, the car part being a key associated with the value in the cdr part.
A form is an S-expression (any) which is legally acceptable to eval; that is, it is syntactically and semantically accepted by the interpreter or the compiler.
A lambda expression must be of the following form, the square brackets are used to indicate zero or more occurances of an expression.
The expression <parameters> is a list of ids which represents the formal parameters or the body (the sequence of <form>s). The evaluation of the body takes place as if the <form>s were enclosed within a progn.
A lambda expression or a code-pointer, the function type is assumed to be expr. This means that the arguments will be evaluated, and that the number of arguments must agree with the number of parameters.
Most functions in this Section return t if the condition defined is met and nil if it is not. Exceptions are noted. Defined are type-checking functions and elementary comparisons.
Functions for testing equality are listed below. For other functions comparing arithmetic values see Chapter 3.
Boolean functions return nil for false; anything non-nil is taken to be true, although a conventional way of representing truth is as t. Note that t always evaluates to itself, its value cannot be redefined. Nil may also be represented as (). As a matter of style, () should be used to refer to an empty list. The Boolean functions and, or, and not can be applied to an object of any type. And and or may also be used as control structures (see Section 8.2 for more information).
Since PSL treats any value which is non-nil as a representation for true, there is no clear distinction between an arbitrary function and a boolean function. However, the three functions presented here are by far the most useful in constructing more complex tests from simple predicates.
The following functions are used in converting data items from one type to another. They are grouped according to the type returned. Numeric types may be converted using functions such as fix and float, described in Section 3.2.
The id which is returned from an application of intern to a string will have the string as its print name. Most identifiers have lowercase print names (even though you may type in lower case letters), but interning ”ABC” yields an id with a lower case print name.
The maximum number of characters in any token is system dependent, around 5000 can be expected to be allowed.
If one refers directly to an identifier (for example ’newone), the reader will apply intern to the string of characters it has read (”NEWONE”). In the example, the identifier created by the call on newid is different from the one created by the reader when it read ’newone.
Up | Next | Prev | PrevTail | Front |