Using keywords in LOOP avoids pollution of package read-tables. Here is what this means.
Define a package named LOOP-SYMBOLS and run the LOOP example from above using ordinary Lisp symbols:
Code: Select all
CL-USER> (defpackage "LOOP-SYMBOLS")
#<PACKAGE "LOOP-SYMBOLS">
CL-USER> (in-package "LOOP-SYMBOLS")
#<COMMON-LISP:PACKAGE "LOOP-SYMBOLS")
LOOP-SYMBOLS> (cl:loop for x from 1 to 10 collect x)
(1 2 3 4 5 6 7 8 9 10)
Print the list of symbols that had been interned in the read-table of the LOOP-SYMBOLS package by LOOP using ordinary Lisp symbols:
Code: Select all
LOOP-SYMBOLS> (cl:do-symbols (x) (cl:print x))
FOR
TO
COLLECT
FROM
X
COMMON-LISP:NIL
The symbols FOR, TO, COLLECT, and FROM have been interned unnecessarily in the read-table of the LOOP-SYMBOLS package, wasting memory for no particular purpose. The LOOP macro identifies its keyword symbols via
SYMBOL-NAME, the LOOP keyword symbols do not need to be interned in the current LOOP-SYMBOLS package at all.
Go back into the CL-USER package:
Code: Select all
LOOP-SYMBOLS> (cl:in-package "CL-USER")
#<PACKAGE "COMMON-LISP-USER">
Define a package named LOOP-KEYWORDS and run the LOOP example from above using Common Lisp keyword symbols, prefixed with colons:
Code: Select all
CL-USER> (defpackage "LOOP-KEYWORDS")
#<PACKAGE "LOOP-KEYWORDS">
CL-USER> (in-package "LOOP-KEYWORDS")
#<COMMON-LISP:PACKAGE "LOOP-KEYWORDS")
LOOP-KEYWORDS> (cl:loop :for x :from 1 :to 10 :collect x)
(1 2 3 4 5 6 7 8 9 10)
Print the list of symbols that had been interned in the read-table of the LOOP-KEYWORDS package by LOOP using Common Lisp keyword symbols:
Code: Select all
LOOP-KEYWORDS> (cl:do-symbols (x) (cl:print x))
X
COMMON-LISP:NIL
Now only the symbol X has been interned in the read-table of the LOOP-KEYWORDS package, because all keyword symbols have been automatically interned in the KEYWORD package, not in the current LOOP-KEYWORDS package.
Using Common Lisp keywords, prefixed with colons, saves memory if you use LOOP in different packages because keyword symbols always are interned in the KEYWORD package and not in every current package anew.
This is a well-known idiosynchrasy of the LOOP macro. LOOP treats its keyword-symbols like Common Lisp keywords, with no specific need to prefix them with colons, but without colons the symbols get automatically interned in the current package, even if the LOOP macro doesn't need this at all.
Common Lisp's LOOP macro can go even one step further, using uninterned symbols, which do not get interned anywhere:
Code: Select all
CL-USER> (loop #:for x #:from 1 #:to 10 #:collect x)
(1 2 3 4 5 6 7 8 9 10)
Here only the symbol X gets interned, the symbols #:for, #:from, #:to, and #:collect are uninterned throw-away symbols.
- edgar