kyle_burton ([info]kyle_burton) wrote,
@ 2008-03-10 20:57:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Keyword symbols vs non-keyword symbols

It took too long for it to really click so while I'm thinking about this again I'm writing it down. There are good reasons why you should avoid using symbols of the form 'foo in preference to :foo. The main semantic difference is that the one preceded with a single quote is tied to the package where it occurrs, while the one preceded by the colon is placed within the keyword package.

What this means to you and your code may vary. One immediate reason to use keyword symbols (the ones that start with a colon) is that they are the same everywhere - they are equal (eq even). This means that they're shared - if you take symbols as arguments, or return symbols as values, then the keyword symbols will be easier to use. You won't have to export them from your package for them to be accessible (except in very rare, unhygenic, cases, eg: aif).

CL-USER> (defpackage :foo                                                                                                    
           (:use :common-lisp)                                                                                                        
           (:export :qux))
#<PACKAGE "FOO">
CL-USER> (in-package :foo)
#<PACKAGE "FOO">
FOO> (defun qux ()                                                                                                           
       'bar)
QUX
FOO> (equal 'bar (qux))
T
FOO> (in-package :cl-user)
#<PACKAGE "COMMON-LISP">
CL-USER> (equal 'bar (foo:qux))
NIL
CL-USER> 

That last one there was somehow confusing to me for a long time. Using keyword symbols solves that issue neatly:

CL-USER> (defpackage :foo                                                                                                         
  (:use :common-lisp)                                                                                                        
  (:export :qux))
#<PACKAGE "FOO">
CL-USER> (in-package :foo)
#<PACKAGE "FOO">
FOO> (defun qux ()                                                                                                           
  :bar)
STYLE-WARNING: redefining QUX in DEFUN                                                                                       
QUX
FOO> (equal :bar (qux))
T
FOO> (in-package :cl-user)
#<PACKAGE "COMMON-LISP">
CL-USER> (equal :bar (foo:qux))
T
CL-USER> 

The other reason to use them is that they're not just interned for the package they were defined in, but all keyword symbols are interned in the keyword package - saving memory in your running instance.

This point was lost on me until I started using packages seriously. I had no context for understanding it until I started using packages to organize my code.

In general you should probably be using keyword symbols as your default.



Advertisement


(No comments)

Post a comment in response:

From:
Help
Identity URL: 
Username:
Password:
Don't have an account? Create one now.
Subject:
No HTML allowed in subject
   Help
Message:

 
Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…