John Thingstad <john.thingstad@chello.no> wrote:
+---------------
| '#+ test expression' runs expression if test is t used
| tha same way #ifdef is used in C
+---------------
Uh... This is somewhat misleading, especially since the OP is an
acknowledged newbie. First, there's no "running" implied at all --
this is purely a READ-time conditional, and applies to *any* READ,
not just ones which result in code, e.g., in CMUCL:
> (read)
(a b #+cmu c d e #-cmu f g) ;I typed this
(A B C D E G)
>
[I have used this occasionally to conditionalize data files built of
s-exprs.]
Second, when you say "if test is t", well, not really. That is, a feature
test is not an normal Lisp expression which is evaluated for a boolean
result using the ordinary rules for Lisp evaluation, as the term "test"
might ordinarily imply. Rather, a "test" here is a special form called
a "feature expression", which consists *only* of symbols (naming items
on the features list) and a few combining operators (AND, OR, & NOT).
A feature expression consisting of just a symbol "succeeds" or "fails"
depending on whether the feature named by the symbol is an element of
the list held by the variable *FEATURES* at the time the read occurs.
A complex feature expression succeeds or fails based on the obvious
AND/OR/NOT combination of the named feature(s):
> (read)
(a b #+cmu c1 #+allegro c2 d e #+(not (or cmu allegro)) f g)
(A B C1 D E G)
>
which could also be written as this:
> (read)
(a b #+cmu c1 #+allegro c2 d e #-(or cmu allegro) f g)
(A B C1 D E G)
>
The features list can be altered during the life of a given Lisp image,
e.g., by loading some library that modifies *FEATURES*, so some care must
be taken when using them.
> #+foo "foo" #-foo "bar"
"bar"
> (push :foo *features*)
(:FOO :ASDF :PCL-STRUCTURES :PORTABLE-COMMONLOOPS :PYTHON :PCL
:ELF :FREEBSD4 :FREEBSD :BSD :UNIX :LINKAGE-TABLE :GENCGC :MP
:PENTIUM :I486 :X86 :IEEE-FLOATING-POINT :ANSI-CL :COMMON-LISP
:COMMON :NEW-COMPILER :HASH-NEW :COMPLEX-FP-VOPS
:CONSERVATIVE-FLOAT-TYPE :RANDOM-MT19937 :RELATIVE-PACKAGE-NAMES
:CMU18E :CMU18 :CMU)
> #+foo "foo" #-foo "not-foo"
"foo"
>
Note that the feature test itself (though not the expressions which
follows it) is read with *PACKAGE* temporarily bound to KEYWORD, so
the elements of the features list should be keywords, too. [Yes, you
can hack around this, but it's not recommended for normal use.]
Finally, as with normal AND & OR special operators, the AND & OR
feature expression combiners succeed or fail (respectively) when
given the empty list, that is, #+(and) always succeeds and #+(or)
always fails. Conversely, #-(and) always fails and #-(or) always
succeeds.
You will see code that uses #+nil to "comment out" a complex s-expr.
There was a long thread here in c.l.lisp some time back which discussed
why this is a bad idea, and suggesting using #-(and) for this instead.
I like and use this latter form, since the normal connotations of + and -
are preserved: #+(and) always reads the following expression, and #-(and)
always ignores it.
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607