[Gardeners] How to name symbols
Pascal Bourguignon
pjb at informatimago.com
Fri Apr 28 21:31:30 CDT 2006
Stuart Sierra writes:
> Pascal Bourguignon <pjb at informatimago.com> writes:
> > Jonathan Fischer writes:
> >> Ditto the thanks! I've a question though: is there any difference
> >> between using the keyword symbols and normal symbols in the exports
> >> list?
> >
> > Yes.
> > Try this:
> >
> > (in-package :cl-user)
> > (defpackage mypackage
> > (:use :common-lisp)
> > (:export foo bar))
> > (use-package 'mypackage)
> >
> > Remember that symbols are interned by the reader when they are read,
> > in the current package.
> >
> > You can use :keywords, or #:uninterned-symbols, or "STRINGS".
>
> I was thinking, as I wrote about colon syntax (glad people
> liked it, by the way) that it would be helpful to explain
> the various ways of identifying symbols by name when
> creating packages and the like. Many standard macros accept
> 1) normal interned symbols, 2) keyword symbols, 3)
> uninterned symbols, or 4) strings. I think the HyperSpec
> calls these arguments "designators."
>
> It's not always clear which form one should use, and
> different styles abound. Is there a "standard" way?
Well, it works by elimination.
For example, the LOOP macro only uses the symbol names of its key words.
So you can use :WHILE #:WHILE, WHILE, THIS-PACKAGE:WHILE, or THAT-PACKAGE:WHILE.
But if you use WHILE, you will eventually encounter the case where
you've interned this WHILE in the current package by using it in a
LOOP form and suddenly you're trying to impor a symbol named WHILE
from some other package, and you get a name collision. So you
eliminate this use case, and choose :WHILE, because it let you avoid
this name collision, and is shorter than #:WHILE, or
THIS-PACKAGE:WHILE.
Same with DEFPACKAGE et al., where you can use string designators,
that is symbols or strings. As I explained, using symbols newly
interned in the current package will give name collisions when you
later try to import (use-package) the package you just defined. So you
eliminate this use case. Using keywords leads to a big pollution of
the KEYWORD package: for all exported symbol, you have a duplicate
symbol in the KEYWORD package. Using uninterned symbols is ugly
#:sym, and you lose more space than with strings, since you have to
allocate a symbol in addition to the symbol name. So by elimination,
you see that the best is to use only strings in these macros.
Since writing a keyword is easier than writing a string, for
interactive use, it's acceptable to use keywords instead of strings,
but in programs, I always use strings, to avoid growing indefinitely
the KEYWORD package.
Note that this reasoning doesn't appear in any text (well, now it
appears in this message, and I may have already explained it in cll).
But you can just think it out yourself, just knowing what happens when
you write the various cases:
symbol
:symbol
#:symbol
"SYMBOL"
Which is explained in excruciating details in the second and twenty
third chapters of CLHS, or explained more or less formally in any CL
tutorial.
--
__Pascal Bourguignon__ http://www.informatimago.com/
Kitty like plastic.
Confuses for litter box.
Don't leave tarp around.
More information about the Gardeners
mailing list