AutoLISP Learning Series - Lesson One: The Elements of Lists AutoLISP is one of several programming languages built into every copy of AutoCAD®. The other languages include Menu Macro, Script, DIESEL and DCL or Proteus. AutoLISP is by far the most flexible and powerful of these.
AutoLISP is both a subset and an extension of the parent language LISP. LISP is one of the oldest of existing modern high-level computer programming languages and perhaps the oldest still in daily use. LISP is an acronym of LISt Processing. As you might expect, LISP is concerned largely with lists. In fact, the fundamental structure for all data processed in LISP is a list. Some Rules, Definitions and ConventionsIn LISP (and therefore AutoLISP), a list is defined as a collection of data objects enclosed within a matching set of parentheses. To begin a list, you type ( and to end a list you type ). A typical LISP list might look something like this:
(+ 7 8 )
Lists can contain two types of objects: individual objects (called atoms) and other lists. The data within a list, whether individual atoms or other lists, must be separated by at least one space. As always, there is an exception to this rule: a list can be "empty", that is, a list can contain neither an atom nor another list. In AutoLISP, an empty list would look something like this: ( ) or even this: ( ). Since the opening and closing parentheses merely delimit or define the beginning and ending of a list, there need not be a space separating these symbols from enclosed atoms or lists. By convention, however, spaces are not placed after opening or before closing parentheses. This makes the list easier to read. And, as you may have guessed, anywhere a space is required, two or more spaces are acceptable.
Here is another rule: almost without exception, AutoLISP is case insensitive. The AutoLISP function 'read' is exactly equivalent to 'READ' or even 'rEaD'. By convention, however, AutoLISP code is generally written and appears on the printed page in either all lower case or with an initial capital letter for individual "words". Again, this practice is adopted solely for readability and exceptions are not uncommon. AtomsAs mentioned above, there are two types of objects in AutoLISP: atoms and lists. Atoms and lists are mutually exclusive; anything that is an atom cannot be a list and vice versa. Again, there is an exception to this rule: the object NIL can be both an atom and a list, as we will see later in this series. Lists, of course, can contain atoms as well as other lists. All of this will become clearer and make more sense when we discuss AutoLISP expressions.
So far, the concept of a list should be fairly clear, but what is an atom? Of course, a true AutoLISP programmer will tell you that an atom is anything that is not a list but that doesn't get us very far at this point. A better answer is: atoms can be just about anything of value in composing an AutoLISP list, expression or program. Specifically, atoms can be integers, real numbers, text strings, AutoLISP functions or special objects that correspond to AutoCAD entities, selection sets and files. Here are some examples of atoms:
22 |
the integer 22 |
22.6 |
the real number 22.6 |
"The Rose Tattoo" |
a text string |
Setq |
a built-in AutoLISP function |
C:probe |
a user-defined symbol |
With the exception of built-in, or native, AutoLISP functions and user-defined symbols, the value of any atom is itself. The atom 34, for example, has a value of 34; the atom 2.1417 has a value of 2.1417, and so on. This concept of an atom having a value equal to its "face value" may seem rather obvious but it needs to be said; it will help you understand slightly more complicated concepts later on. ListsLists are AutoLISP objects too. And as you now know, list are composed of atoms and/or other lists. As you also know, lists are syntactically defined as anything bounded by a matching set of parentheses. So you can see what some actual AutoLISP lists look like, here are a few examples:
(+ 3 7) |
an arithmetic expression, add 3 the integers 3 and 7 |
(* 2 (+ 3 7)) |
an arithmetic expression, multiply the sum of 3 and 7 by 2 |
(setq xyz 17) |
a function with arguments |
Anything bounded by matching parentheses must be a list; anything not bounded by matching parentheses must be an atom.
The individual objects in a list are also known as the elements of a list. Look at the following list:
(+ 22 5)
This list contains three elements, each an atom in this case. Specifically, this list is composed of a function and two integers. Now look at the following list:
(+ 1 (+ 2 3))
This is an example of a list that contains another list as one of its elements. The larger, or upper level list is composed of a function (an atom), an integer (another atom) and a list. The shorter list itself is composed of three atoms: a function and two integers. Lists that serve as an element of another, larger, list are called nested lists. And of course a nested list may also contain a nested list, which may contain a nested list, and so on. There is no limit to the level of nesting. In fact, nested lists are the rule, rather than the exception in AutoLISP.
Keeping in mind that all lists are formed with a matching set of parentheses, deeply nested lists provide one of the most troublesome aspects of writing (and reading) AutoLISP code. Making sure that each opening parenthesis is matched by a corresponding closing parenthesis is, frankly, difficult. Add to this the requirement that the parentheses need not only match numerically but must be placed correctly in relation to all of the other atoms and lists within the upper level list, and it is easy to see that multiple-level, or nested, lists provide the source of many errors, or bugs, in AutoLISP code. It also provides an alternate tongue-in-cheek definition of the LISP acronym: "Lost In Stupid Parentheses." Consider the relatively simple list:
(setq hyp (sqrt (+ (* aa aa) (* bb bb))))
and you will see how quickly the parentheses can become visually confusing.
We need to again mention both the "empty" list and the atom NIL again. It is important that every programming language have a data element that evaluates to "no value," "nothing,""nada," "null," "zip". In AutoLISP, this object is called NIL. Since AutoLISP is composed of only atoms and lists, there must be both an atom and a list that have "no value". To express the concept of nil as an atom, we just type NIL (usually typed all caps for clarity). To express nil as a list, we type an empty list: ( ). Here are two examples of the nil concept:
(setq xyz nil)
(setq file-name ( ) )
Go to the Next Lesson: Evaluating Lists and Expressions |