Table of Contents

LISP Syntax

Important feature of LabLisp, as of any other LISP, is that the LISP code is a data structure (list of lists, or tree, of atoms) and lists are fundamental LISP data structure. LabLisp expression consists of symbols, literals and parentheses that organize the list into sub-lists. Following is example of an expression:

(foo (bar 1.3 a) (boo "text" 14))

What we see is a list, containing symbol foo and two sub-lists. First sub-list contains symbol bar, literal floating-point number 1.3, and symbol a (possibly variable name). Second sub-list contains symbol boo, string literal “text” and integer literal 14. Symbols foo, bar and boo appear first in their lists, and should name functions. Actually, all LISP operators are applied in the functional syntax, appearing at the first position of the expression. So simple addition will be written as

(+ 3 5)

This expression can be directly entered to LISP and evaluates to 8. LISP programs are written in a functional style. We can understand the first example expression as function foo that takes two parameters, and we call the expression (foo x y) a function-application form. Before the function is invoked (applied), the two sub-lists need to be evaluated to something the foo function accepts as arguments. The form (bar 1.3 a) is another function-application, where the arguments are evaluated first: literal 1.3 evaluates to itself and symbol a should be defined variable that evaluates to its value (let’s say another number). Analogically for the (boo “text” 14) form, which could be application of boo function to literal arguments “text” and 14. All together, this means the arguments of the form bar are evaluated first (left to right), then the function bar is applied, then the arguments of boo are evaluated and that function is applied, finally, the complete expression with function foo is evaluated last.

The examples above consist of lists of atoms. In LabLisp, atoms can have one of following types: symbol, integer, float, string, function object or package. Symbol can be, for now, understood as a variable or a function name. The last two types (function and package) are not trivial, and we will discuss them later. Any white space (space, line break, tab) is considered as separator between the list items and has no other special role in the code. Line breaks or indents serve only esthetic purposes.

Escaping

In LISP syntax, as in the examples above, we encounter some special characters. Obviously, the parentheses ( ) hold a unique role as list delimiters. The quotation marks (double quotes) delimit string. Everything between a pair of quotation marks is considered a string. With that comes the need for single character escape symbol \ (backlash). For example, if we want to include quotations mark in our string we need to escape the character, otherwise our string would be broken apart:

"she said \"ouch\" suddenly"

Backlash symbol escapes single character. If we want to escape several characters in a block, we contain them in bars | |.

"here come three |"""| quotation marks"

Commenting

Comments in LISP code are marked with one or more semicolons, which will cause the LISP interpreter (called reader) to ignore everything behind until the end of line

(+ 3 6)   ; example of addition

It is conventional to highlight comments with multiple semicolons depending on importance. Single semicolon appears on the line with command. Two-semicolon comments are between commands. Three semicolons typically appear in comment describing a block of code (function definition etc.) and four-semicolon comment is reserved for header of whole source file.

When the programmer needs to comment-out whole block of code, there is also block-comment pair of symbols

#|this is out|#

Block-comments are counted and leveled, so it is possible to surround the part of block-commented code with new pair of block-comment symbols.

Special reader characters

In more developed LISP languages, the # symbol serves as marker for several reader operations and macros, but in LabLisp there are only few and will be discussed in the following chapter.

LISP environments feature another syntactic curiosity: auto-upper-casing of symbol name strings (not string literals). It is conventional to write lisp source code in lower-case, but the reader converts all lower-case to upper case. So, symbols written in the code as aaa, AAA, aAa etc. will all be converted to AAA and refer to the same symbol. It is possible to force the symbol name to have lower-case with escaping: a\aa, will be read as AaA and will not be equivalent to AAA. Therefore, while normally auto-upper-casing all symbol names, LISP still is case sensitive.

There are some other important special characters: (quote) ` (backquote) , (comma) ,@ (comma-at) and ,. (comma-dot). These characters appear before an expression and serve as switch between code-mode and data mode. This topic will be discussed in more details later. Let’s just give one example for quote:

(f a b)   ;is code, will be evaluated as function form f(f a b)  ;switched to list data structure with three symbols

Similarly looking . (dot) #' (sharp-quote) have different purpose, and we will discuss them in the next chapters.

Style

Apart from that, LISP is very benevolent with symbol names. Many different characters are allowed. For example, <_!*!_> is perfectly fine as symbol name. But good habit is to write descriptive symbol (function, macro) names in lower-case with hyphens (same as minus sign) separating words:

my-first-function

next → LabLISP REPL and multitasking