Page 1 of 1

loop keywords

Posted: Thu Oct 18, 2012 1:20 am
by stackman
Hi,

I see sometimes loop forms written as follows.

Code: Select all

(loop :for x :from 1 :to 10 :collect x)


Why do some people prefix the loop keywords with a colon?
Is this required by some implementations?
The hyperspec insists on the fact that "Loop keywords are not true keywords."
So why does the use of true keywords actually work?

Also I am not sure to understand how these keywords are implemented.
May be someone can provide a simple macro using such a keyword, for example
an if form that takes a "then" keyword?

Re: loop keywords

Posted: Thu Oct 18, 2012 11:34 am
by pjstirling
LOOP uses SYMBOL-NAME to locate the various symbols that control its clauses, since SYMBOL-NAME doesn't include any info for the package of the symbol, it doesn't matter which package the symbol used lives in. If you use the keyword package then your own package won't have 'spurious' symbols, which matters for C-c tab completion, but is otherwise pretty harmless I think. I read somewhere that true keywords also can be a help for quickly identifying the structure of the loop, but I never use LOOP in my code, so I can't comment on how helpful it might be.

Re: loop keywords

Posted: Thu Oct 18, 2012 2:04 pm
by edgar-rft
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

Re: loop keywords

Posted: Fri Oct 19, 2012 1:38 am
by stackman
Ah, I understand now. Thanks for the thorough answer.

Re: loop keywords

Posted: Fri Oct 19, 2012 6:20 am
by Paul
stackman wrote: Why do some people prefix the loop keywords with a colon?
They have a really bad sense of aesthetics :)