Symbols in defpackage

Discussion of Common Lisp
Post Reply
pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Symbols in defpackage

Post by pjstirling » Sun Dec 12, 2010 8:01 pm

Hi,

A few weeks ago (I've been too busy with other stuff to get around to this until now) I was reading a post via planet.plis.org talking about how he sets up new projects and something that I'm unclear about is that he uses #: (I had to look it up) to make un-interned symbols:

Code: Select all

(defpackage #:swatchblade
  (:use #:cl)
  (:shadowing-import-from #:vecto
                          #:with-canvas
                          #:rounded-rectangle
                          #:set-rgb-fill
                          #:save-png-stream))
but in e.g. cl-sqlite (and others) they use plain keywords:

Code: Select all

(defpackage :sqlite
  (:use :cl :iter)
  (:export :sqlite-error
           :sqlite-constraint-error
           :sqlite-error-db-handle
           :sqlite-error-code
           :sqlite-error-message
           :sqlite-error-sql
           :sqlite-handle
           :connect
           :set-busy-timeout
           :disconnect
           :sqlite-statement
           :prepare-statement
           :finalize-statement
           :step-statement
           :reset-statement
           :clear-statement-bindings
           :statement-column-value
           :statement-column-names
           :statement-bind-parameter-names
           :bind-parameter
           :execute-non-query
           :execute-to-list
           :execute-single
           :execute-single/named
           :execute-one-row-m-v/named
           :execute-to-list/named
           :execute-non-query/named
           :execute-one-row-m-v
           :last-insert-rowid
           :with-transaction
           :with-open-database))
From reading the hyperspec, when you use a symbol for a package designator then it reads only the name of the symbol, so any symbol, including keywords are explicitly allowed, but I'm not so sure about the export list.

I'm assuming that Zach is doing it this way for a reason.

(Wild speculation) Is using a keyword in an export going to cause the package to put its function inside the symbol in the keyword package? (Which would then mean potential clashes if another package used the same symbol for one of its functions)

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Symbols in defpackage

Post by ramarren » Mon Dec 13, 2010 12:18 am

pjstirling wrote:From reading the hyperspec, when you use a symbol for a package designator then it reads only the name of the symbol, so any symbol, including keywords are explicitly allowed, but I'm not so sure about the export list.
Hyperspec wrote: (:export {symbol-name}*)*

symbol-name---a string designator.
Export list is the same as all other lists in DEFPACKAGE, its contents are used for names only. The difference between symbols in keyword package and uninterned symbols, is a minor mostly stylistic one. When the reader reads the form all non-#: are interned in their package, and they stay interned even if they are not used as symbols. Uninterned symbols are garbage collected when they are no longer needed. This means that if you use keyword symbols they will be interned in keyword package, and so use memory and appear in autocompletion lists. Also, this will result in a difference between loaded and compile-loaded environment (since a FASL file will only have names, loading it will not result in interning those additional keyword symbols).

I don't think there is any non-contrived situation where any of this matters (autocompletion pollution is most likely to be noticeable), but still they are easily avoided by using #:, so many people do.

findinglisp
Posts: 447
Joined: Sat Jun 28, 2008 7:49 am
Location: Austin, TX
Contact:

Re: Symbols in defpackage

Post by findinglisp » Mon Dec 13, 2010 2:55 pm

pjstirling wrote:(Wild speculation) Is using a keyword in an export going to cause the package to put its function inside the symbol in the keyword package? (Which would then mean potential clashes if another package used the same symbol for one of its functions)
Ding, ding, ding! We have a winner!

Yes, essentially this is it. A package designator simply uses the symbol for its text value, so they can come from any package. When the reader is reading the DEFPACKAGE form, it's also interning those symbols from the source text as it reads them. In order to avoid clashes, it's traditional to either put those into the keyword package or use uninterned symbols (which are effectively one-off, created as they are read and forgotten about as soon as you loose all the references to them; reading another uninterned symbol of the same name creates a new symbol each time).

Since symbols in the keyword package are all created with bindings to themselves, you can't really create a symbol clash using either keyword symbols or uninterned symbols, but keyboard symbols will be interned and will hang around long after you might have gotten rid of them. This can bloat your image, etc. Typically, this not a big deal as the amount of memory is probably not large, but people who get uptight about things like that will typically use uninterned symbols to allow the system to garbage collect them at the earliest opportunity.

I typically use uninterned symbols when I'm creating a library just because I want to avoid creating extra junk for my potential users, but I'm probably overanalyzing the situation.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: Symbols in defpackage

Post by pjstirling » Mon Dec 13, 2010 5:36 pm

Thanks for clarifying that for me.

Post Reply