loop keywords

Discussion of Common Lisp

loop keywords

Postby stackman » Thu Oct 18, 2012 1:20 am

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?
stackman
 
Posts: 28
Joined: Sat Oct 06, 2012 5:44 am

Re: loop keywords

Postby pjstirling » Thu Oct 18, 2012 11:34 am

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.
pjstirling
 
Posts: 78
Joined: Sun Nov 28, 2010 4:21 pm

Re: loop keywords

Postby edgar-rft » Thu Oct 18, 2012 2:04 pm

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
edgar-rft
 
Posts: 154
Joined: Fri Aug 06, 2010 6:34 am
Location: Germany

Re: loop keywords

Postby stackman » Fri Oct 19, 2012 1:38 am

Ah, I understand now. Thanks for the thorough answer.
stackman
 
Posts: 28
Joined: Sat Oct 06, 2012 5:44 am

Re: loop keywords

Postby Paul » Fri Oct 19, 2012 6:20 am

stackman wrote:Why do some people prefix the loop keywords with a colon?

They have a really bad sense of aesthetics :)
Paul
 
Posts: 106
Joined: Tue Jun 02, 2009 6:00 am


Return to Common Lisp

Who is online

Users browsing this forum: No registered users and 4 guests

cron