Why do we specifiy packages using pound colon in Common Lisp? - common-lisp

New Common Lisper here. I have seen packages being declared with the pound colon syntax, as in (defpackage #:foo), but I have also seen them defined as plain keywords, as (defpackage :foo).
Which is considered "better"? What is the difference between these two? I read somewhere that pound colon simply means the keyword isn't interned. Is that true? If so, what are the advantages to defining a package with an uninterned keyword?

Package names are strings, but you can designate them using symbols, so you have basically the following options:
1. (defpackage foo ...)
2. (defpackage "FOO" ...)
3. (defpackage :foo ...)
4. (defpackage #:foo ...)
It is true that #:foo is an uninterned symbol, and the reason some people prefer to use that syntax is precisely because it does not "pollute" the current package (1) or the keyword package (3). Usually (1) is a big No because your defpackage form has a side-effect on whatever package is current, which is bad. At least (3) is more deterministic, you always pollute the keyword package.
Note that "polluting" is not so much a problem of having too many symbols in a package, but also the fact that it is harder to reverse the operation: delete-package cleans the package designated by the symbol, but there is still a symbol interned in another package that probably was not there before defpackage (and if it already was there, you don't want to unintern it).
Some people don't mind and use keyword symbols everywhere, and it is not "bad", it just has a potential for being a source of problems in some corner cases. It is usually better to use either a string (2) or an uninterned symbol (4).
The advantage of strings over symbols (interned or not) is that you control the case: it is possible to have different packages with names that are only distinct in case (e.g. "test" vs "TEST"), and while the standard defines how symbols are read by default (upcased), you don't know in advance if your package definition will be read by a Lisp environment that is setup in a standard way or a custom way (e.g. inverting the case before interning).
So ideally it should be more robust to use always literal strings: they do not intern a symbol and the case is explicit.
However, for some reason people tend to prefer writing #:foo: probably because it is not written in uppercase, or because there is no need for quotes, etc. I am not sure why honestly (strings are often a code smell in other circumstances so maybe we tend to avoid them).
Anyway, it has become a bit customary to use uninterned symbols. This is usually not a problem because (i) people tend to use the standard readtable and (ii) in case they customize it, it is quite stable during the execution of a Lisp environment: whether you upcase or downcase the symbol in the defpackage of some package P, the symbol will be read the same way in the (:use P) clause of another defpackage.

Package names are strings. But it is a good idea to specify them as symbols, because this buys you immunity to variants of CL which which do not have the same case behaviour as CL. As an example, Allegro CL has (or used to have: I have not looked at it for at least a decade) a mode where everything was lower-case by default. In that mode (symbol-name 'foo) would be "foo", and all the standard CL symbols were lower-case versions of themselves (so (symbol-name 'symbol-name) was "symbol-name".
If you wanted to write code which had any chance of running in an environment like that, you couldn't give packages names which were strings:
(defpackage "FOO"
...)
would mean that, in future, you'd need to type FOO:x and so on, which was horrible. Even worse, if you said
(defpackage "FOO"
...
(:export "X"))
You'd now have to type FOO:X. And something like this:
(defpackage "FOO"
(:use "CL")
(:export "X"))
would fail dismally because there was no package whose name was "CL" at all: its name, of course, was "cl".
So if you needed things to work with that environment you really wanted to type package names – and symbol names in packages – as symbols.
This also would mean that your code would have a chance of running in some future CL variant which really was lower-case, which many people assumed would probably happen at some point, since case-sensitive lower-case-preferred languages had clearly won by the late 1980s.
Given that there's a question of where you want the names to be interned. For symbols in a package it is generally very undesirable to intern them in the current package:
(defpackage foo
(:export x y z))
(use-package 'foo)
will fail.
So then there are two obvious choices:
intern things in the keyword package;
don't intern them.
It does not make much difference which you do in practice. Personally I intern package names in the keyword package as I want completion to work on them, but do not intern symbol names, because that seems just to be gratuitous clutter. So my package definitions look like
(defpackage :foo
(:use :cl ...)
(:export #:x #:y ...))

Related

deal with readtable case when building symbols inside a macro

I want to build a macro that defines several classes and methods based on symbols that would have a root string (I guess this is not an unusual thing to do in lisp ^^).
dummy example :
(defmacro define-my-stuff (term)
would do such things as
defclass my-super-term-class
defvar *term-variable*
defun do-term ((a-thing *example-term*))
with symbols built upon the "term" macro parameter
How to deal with the different readtable-case so the code can be universally used with the four different type of cases (:UPCASE :DOWNCASE :PRESERVE :INVERT).
I want to be able to use these symbols from source code. So I want the symbols created inside the macro to be built by the reader readtable-case rule that is used by the lisp system.
(The regular is :UPCASE but some uses :DOWNCASE for example).
The only way I have found to do such a thing would be to use the READ-FROM-STRING function (example : (read-from-string (concatenate "term" "-variable"))
But this also interns the symbol as side effect.
So how should I compute a symbol following the readtable-case rule without interning it ?
Is there in function for that in the common-lisp package ?
You can use an uninterned symbol as a string designator:
(string '#:Foo)
=> "FOO"
or=> "foo"
or=> "Foo"
or=> "fOO"
You can create an uninterned symbol:
(read-from-string (concatenate 'string "#:" "term" "-variable")
But you need to be very careful with READ-FROM-STRING when trying to securely read from a not secure string. Common Lisp IIRC lacks a standard symbol parser which only does that operation in isolation - without read time evaluation and without reading arbitrary structures. There is probably in a library somewhere a 'secure' symbol parser, which the also checks the readtable case.

Common lisp about naming packages and using them

I try to use Common Lisp packages, but I have several (probably naming conventions) problems, first is the use of "#:" it seems not necessary but is like sharp-quote in functions that is better to use depending on your context.
(defpackage #:match-test
(:use #:match
#:fiveam
#:cl)
(:export #:run!
#:test-match)
(:documentation "Test package for testing match project 1 of CS202"))
Then is in how to use that package
(in-package #:match-test)
(in-package :match-test)
(in-package match-test)
it works, but when I want to delete that package it only works with:
CL-USER> (delete-package (in-package #:match-test))
#<BOOLEAN <<error printing object>> {2010004F}>
it gives that error, but it makes the job done. It seems working with the package as an object, I also do not understand the hyperspec, is a problem that I need to learn CLOS, that is true I'm a beginner learning Lisp, but I suppose that I can get a easy clarifying for my doubts.
I hope that I said it quite clearly.
Finally I want to say that I used emacs + sly + roswell and
CL-USER> (lisp-implementation-type)
"SBCL"
CL-USER> (lisp-implementation-version)
"1.4.6"
DEFPACKAGE and IN-PACKAGE are defined as macros. They take a literal name - a string designator: foobar, |FOOBAR|, #:FOOBAR, :FOOBAR or "FOOBAR".
DELETE-PACKAGE is a function and expects a string designator, too. But since it is a function, the argument is evaluated. This means: if you want to pass the name, you have to quote it - if it is a symbol not in the keyword package. Strings and keyword symbols are self-evaluating and don't need to be quoted. Valid arguments to DELETE-PACKAGE are for example:
'foobar
'|FOOBAR|
'#:FOOBAR
:FOOBAR or ':FOOBAR
"FOOBAR" or '"FOOBAR"
Since DELETE-PACKAGE is a function, the argument gets evaluated -> you can also evaluate variables, function calls, ... as argument.
The Error: Deleting the current package
LispWorks:
CL-USER 43 > (delete-package (in-package #:match-test))
Error: Cannot delete the current package, #<The MATCH-TEST package, 0/16 internal, 2/16 external>.
1 (abort) Return to top loop level 0.
SBCL:
* (delete-package (in-package #:match-test))
debugger invoked on a SIMPLE-TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {10005605B3}>:
*PACKAGE* can't be a deleted package:
It has been reset to #<PACKAGE "COMMON-LISP-USER">.
Your code tries to delete the current package - you just used IN-PACKAGE to make it the current package - deleting the current package is usually not a good idea. You are shooting yourself in the foot. A Lisp might prevent that (like my example in LispWorks) or allow it - but then you have to live with the consequence.

Variations in invocation of defpackage and in-package

In Graham's book “ANSI Common Lisp” (1996) p. 137 the example illustrating the use of defpackage and in-package goes like
(defpackage "MY-APPLICATION"
(:use "COMMON-LISP" "MY-UTILITIES")
(:nicknames "APP")
(:export "WIN" "LOSE" "DRAW"))
(in-package my-application)
The defpackage invocation uses of character strings to convey package names and list exported symbols. While this style can be seen in older codes the dominant usage today seems to be
(defpackage :my-application
(:use :common-lisp :my-utilities)
(:nicknames :app)
(:export :win :lose :draw))
(in-package :my-application)
The regularity resulting from using the :my-application keyword both in the defpackage and in the in-package invocations is a minor but appreciable difference.
I speculate, the second forms reduces the size of the program in memory because the keywords are all interned in the keyword package while literal character strings stand for themselves and literal character strings with identical contents do not need to share their memory representations. (And if they did, strange results could follow from mutating one of these character strings!)
What are the actual differences between these two forms, and why is the latter preferred over the former?
Besides this, I occasionally see
;; Pay attention to the :export line
(defpackage :my-application
(:use :common-lisp :my-utilities)
(:nicknames :app)
(:export #:win #:lose #:draw))
(in-package :my-application)
The # introduces a reader macro but I am not sure which effects it has on a keyword and not sure how it modifies the defpackage declaration.
tl;dr
Use uninterned symbols, like #:my-package.
String designators
Common lisp has a notion of a string
designator
(see also designators).
This means that operationally symbols in
defpackage are equivalent to
their names.
Which designator to use?
You have 4 options:
1 Interned symbol
E.g.,
(defpackage my-package)
Advantage
Brevity
Disadvantage
Namespace pollution: the symbol my-package is now
interned in the current
*package*.
2 Keyword
E.g.,
(defpackage :my-package)
Advantage
Moderate brevity (one extra character)
Disadvantage
Namespace pollution: the symbol :my-package is now
interned in the standard package
KEYWORD.
3 String
E.g.,
(defpackage "MY-PACKAGE")
Advantage
No namespace pollution.
Disadvantages
Ugly upcase
2 extra characters
4 Uninterned symbol
E.g.,
(defpackage #:my-package)
Advantage
No namespace pollution.
Disadvantages
2 extra characters
The "ugly prefix" is actually a desirable feature because this is the only context where I use uninterned symbols, and emacs highlights them nicely if you add
(font-lock-add-keywords
'lisp-mode
'(("\\(#:\\)\\(\\(\\s_\\|\\sw\\)*\\)"
(1 font-lock-comment-delimiter-face)
(2 font-lock-doc-face))))
to your ~/.emacs.
Your example:
(defpackage "MY-APPLICATION"
(:use "COMMON-LISP" "MY-UTILITIES")
(:nicknames "APP")
(:export "WIN" "LOSE" "DRAW"))
(in-package my-application)
One then typically writes:
(in-package "MY-APPLICATION")
If you use strings in defpackage, then you also would use strings in in-package.
One of the main advantages of using strings or un-interned symbols is to avoid 'polluting' packages with 'unwanted' symbols.
I speculate, the second forms reduces the size of the program in memory because the keywords are all interned in the keyword package while literal character strings stand for themselves and literal character strings with identical contents do not need to share their memory representations. (And if they did, strange results could follow from mutating one of these character strings!)
That's implementation specific and depends on how the macros and the underlying data structures are implemented. For example in LispWorks for the package object: the package name is a string, the nicknames are strings, the use list is a list of package objects, and exported symbols are stored as symbols. Thus the data from the defpackage form is converted as necessary into these.
Note also what the Common Lisp operators for packages would return: package-name returns a string, package-use-list returns a list of package objects, do-external-symbols iterates over symbols. They don't use keywords or un-interned symbols.

Keyword namespace pollution

I understand that the difference between
(defpackage :foo
(:export :bar))
and
(defpackage :foo
(:export #:bar))
is that the latter doesn't intern bar into the KEYWORD package. My question is, is there a point in doing this? It seems like the point of the KEYWORD package is to be used for interning keywords, after all.
A package is used to maintain namespaces of symbols. A package has a name and symbols have names. Usually one gets these names as strings and thus defpackage forms can use strings for the names:
(defpackage "FOO"
(:export "BAR"))
Above package description is not liked by some, since it exposes the case of the identifiers. Usually this is not an issue, but there are non-standard versions of Common Lisp where symbols could be lower-case by default.
Since one can use symbols as names (and only the name is significant) in a DEFPACKAGE form we can write:
(defpackage :foo
(:export :bar))
or
(defpackage #:foo
(:export #:bar))
or even
(defpackage cl-user::foo
(:export cl-user::bar))
CL-USER 22 > (find-symbol "BAR" "FOO")
FOO:BAR
:EXTERNAL
The usual expectation is that unreferenced symbols interned in packages might not be removed by a Garbage Collector (GC) - the Common Lisp standard says nothing about this topic and has no required behavior. So adding new symbols to a package often keeps it growing. This could be a memory leak in some applications.
Another usual expectation would be that unreferenced and uninterned symbols will be freed by a GC.
If you don't mind that there are a lot (whatever that means) symbols in the keyword package, then it is not an issue.
Typical problems with LARGE packages might be:
interned symbols may not be GCed
there MIGHT be some speed cost involved using large packages
For the typical DEFPACKAGE form I would not expect any noticeable problem, so one might prefer one variant for whatever stylistic reasons.

What's the meaning of "#+" in the code of cl-mysql? [duplicate]

This question already has answers here:
operator #+ and #- in .sbclrc
(2 answers)
Closed 6 years ago.
Recently I tried to read code about cl-mysql, but got stuck with the #+.
Tried to google it, but not work, so turn to here
(defun make-lock (name)
#+sb-thread (sb-thread:make-mutex :name name)
#+ecl (mp:make-lock :name name)
#+armedbear (ext:make-thread-lock)
#+ (and clisp mt) (mt:make-mutex :name name)
#+allegro (mp:make-process-lock :name name))
And looks like it is for different backend lisp compiler. But still no idea why write something like this.
Anyone can help me make it clear, thx.
#+ is a reader-macro that checks if a keyword is in the special variable *FEATURES*. If it isn't there, the following form will be skipped over (by the reader; the compiler will never see it). There is also #- which does the opposite.
There are some things that aren't part of the Common Lisp standard, but are important enough that all (or most) implementations provide a non-standard extension for them. When you want to use them in code that needs to work on multiple implementations, you have to use read-time conditionals to provide the correct code for the current implementation. Mutexes (and threads in general) are one of those things.
Of course there may be features provided by third party libraries as well. The contents of *FEATURES* will look something like this:
(:SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF-PACKAGE-SYSTEM :ASDF3.1
:ASDF3 :ASDF2 :ASDF :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :64-BIT
:64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS
:C-STACK-IS-CONTROL-STACK :COMMON-LISP :COMPARE-AND-SWAP-VOPS
:COMPLEX-FLOAT-VOPS :CYCLE-COUNTER :ELF :FLOAT-EQL-VOPS
:FP-AND-PC-STANDARD-SAVE :GENCGC :IEEE-FLOATING-POINT :INLINE-CONSTANTS
:INTEGER-EQL-VOP :INTERLEAVED-RAW-SLOTS :LARGEFILE :LINKAGE-TABLE :LINUX
:LITTLE-ENDIAN :MEMORY-BARRIER-VOPS :MULTIPLY-HIGH-VOPS :OS-PROVIDES-DLADDR
:OS-PROVIDES-DLOPEN :OS-PROVIDES-GETPROTOBY-R :OS-PROVIDES-POLL
:OS-PROVIDES-PUTWC :OS-PROVIDES-SUSECONDS-T :PACKAGE-LOCAL-NICKNAMES
:PRECISE-ARG-COUNT-ERROR :RAW-INSTANCE-INIT-VOPS :SB-DOC :SB-EVAL :SB-FUTEX
:SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK :SB-SOURCE-LOCATIONS :SB-TEST
:SB-THREAD :SB-UNICODE :SBCL :STACK-ALLOCATABLE-CLOSURES
:STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS
:STACK-ALLOCATABLE-VECTORS :STACK-GROWS-DOWNWARD-NOT-UPWARD :SYMBOL-INFO-VOPS
:UNIX :UNWIND-TO-FRAME-AND-CALL-VOP :X86-64)
So if you wanted to write code that depends on Quicklisp for example, you could use #+quicklisp. If you wanted code that is only run if Quicklisp is not available, you'd use #-quicklisp.
You can also use a boolean expression of features. For example,
#+(or sbcl ecl) (format t "Foo!")
would print Foo! on either SBCL or ECL.
#+(and sbcl quicklisp) (format t "Bar!")
would only print Bar! on SBCL that has Quicklisp available.
One could imagine that we can write:
(defun make-lock (name)
(cond ((member :sb-thread *features)
(sb-thread:make-mutex :name name))
((member :ecl *features*)
(mp:make-lock :name name))
...))
But that does usually not work, because we can't read symbols when their package is not existing and some packages are implementation/library/application specific. Packages are not created at read time in a lazy/automatic fashion.
In Common Lisp, reading a symbol of a package, which does not exist, leads to an error:
CL-USER 1 > (read-from-string "foo:bar")
Error: Reader cannot find package FOO.
1 (continue) Create the FOO package.
2 Use another package instead of FOO.
3 Try finding package FOO again.
4 (abort) Return to level 0.
5 Return to top loop level 0.
In your example sb-thread:make-mutex is a symbol which makes sense in SBCL, but not in Allegro CL. Additionally the package SB-THREAD does not exist in Allegro CL. Thus Allegro CL needs to be protected from reading it. In this case, the symbol sb-thread:make-mutex will only be read, if the the feature sb-thread is present on the cl:*features* list. Which is likely only for SBCL, or a Lisp which claims to have sb-threads available.
The feature expressions here prevents the Lisp from trying to read symbols with unknown packages - the packages are unknown, because the respective software is not loaded or not available.

Resources