What keywords are interned in the KEYWORD package by default? I noticed some differences between SBCL and CLISP's initial interned keywords right after I start their REPLs. Are the default interned symbols in the KEYWORD package supposed to vary between implementations?
In SBCL:
(find-symbol "CL" "KEYWORD") ; -> :CL, :EXTERNAL
(find-symbol "CL-USER" "KEYWORD") ; -> :CL-USER, :EXTERNAL
(find-symbol "COMMON-LISP" "KEYWORD") ; -> :COMMON-LISP, :EXTERNAL
(find-symbol "COMMON-LISP-USER" "KEYWORD") ; -> NIL, NIL
In CLISP:
(find-symbol "CL" "KEYWORD") ; -> NIL, NIL
(find-symbol "CL-USER" "KEYWORD") ; -> NIL, NIL
(find-symbol "COMMON-LISP" "KEYWORD") ; -> :COMMON-LISP, :EXTERNAL
(find-symbol "COMMON-LISP-USER" "KEYWORD") ; -> NIL, NIL
What keywords are interned in the KEYWORD package by default?
Any which the implementation wants/needs. Remember, a Lisp implementation may include a compiler, an I/O system, an object system, interfaces to the operating system, development tools, ways to do networking, graphics libraries, terminal libraries,...
Each of those (implementation, library, extension, ...) may use keywords in their implementation code. Since there is only one keyword package, all keywords end up in this same package.
Neither in the standard, nor by convention, there are expectations what symbols are present in the keyword package - beyond those which may be mentioned in the standard.
Related
Using
(write 'a)
give result A, so I guess 'a is the same as #\A (representation of character A in Lisp). But
(write-char 'a)
give error *** - WRITE-CHAR: argument A is not a character. So what is 'a?
Using
(write #\a)
give result #\a so I guess, for write function, #\a is used as a string; but why not need put #\a in double quote, i.e "#\a".
I already read about write, write-char function at here and here; and hard to find expected results when searching with keywords lisp 'a
TL;DR: 'a is not a character.
Lisp has some basic datatypes:
String, e.g. "Hello, world!", the same as an array of characters
Character, e.g. #\A. A lisp implementation is allowed to have multiple types of character (eg Unicode and ascii), but most do not.
number, e.g. 1.5. These can be subdivided into fixnums, bignums, and various kinds of float, as well as subtypes like bit.
Symbols, e.g. 'a, sometimes written A. A symbol is basically a pointer to a string plus some extra information, and typically symbols are looked up (aka interned) in a hash table called a package, so that if two symbols look the same, they are equal as pointers. The lisp reader (ie parser) normally converts symbols to uppercase before interning them
Lisp code is made of lisp objects and normally a symbol is evaluated as a variable lookup, so if you try to write the symbol A with (write a) you get an error about A being undefined.
So how can one express the symbol A in lisp? Well there is a special quote operator:
CL-USER> (quote a)
A
The way lisp evaluates (quote x) is that it just returns whatever lisp object is in the source code x, so e.f. (quote (a b c)) evaluates to the list of the symbols A, B, and C
Finally, lisp has syntactic sugar 'x for (quote x), so '(a b c) is exactly the same as (quote (a b c))
CL-USER> (list 'quote (list 'a 'b 'c)
'(A B C)
Finally, the function write normally tries to write objects in lisp syntax. So you get:
CL-USER> (write "good")
"good"
"good"
Note one is the string written by write And one is the return value printed by the REPL.
CL-USER> (read-from-string "A")
A
CL-USER> (read-from-string "#\\A")
#\A
So you see that write Tried to format things in a way that they can be understood by read.
Characters, Symbols, ...
So what is 'a
'a is a shorter notation for (quote a). (quote a) evaluates to the symbol a.
so I guess, for write function, #\a is used as a string; but why not need put #\a in double quote, i.e "#\a".
No, #\a is a character object.
Read an intro book instead of the language reference
You might want to read an introductory Lisp book and not the more complex language reference. I'd recommend Paul Graham's book ANSI Common Lisp or Common Lisp: A Gentle Introduction to Symbolic Computation by David S. Touretzky. The latter is available for download.
Or in other words: Is it possible for a variable in CL not to be (part of) a symbol?
I think I may have a profound misconception about variables in CL.
I always thought CL has no variables, only symbols, and symbols have (among other properties) a name and a value cell (which is the variable).
And when someone said "variable x has the value 42" I thought it was short for "the value cell of the symbol named x stores the value 42".
But this is probably wrong.
When I type
> (let ((a 42))
(type-of 'a))
SYMBOL
; caught STYLE-WARNING:
; The variable A is defined but never used.
is the lexical variable a in this example a fully fleshed symbol whose value cell has been set to 42?
Because the warning The variable A is defined but never used suggests otherwise and it appears that the lexical variable is not the same thing as the symbol a in the following form (type-of 'a).
Common Lisp has two data types which have a special meaning for evaluation:
cons cells / lists -> used in Lisp source code, lists are Lisp forms
symbols -> used as names for various purposes
If you want to use them as data in Lisp code, then you have to quote them.
Both are used in the Lisp source code, but once you compile code, they may disappear.
Variables are written as symbols in the source code. But in compiled code they may go away - when they are lexical variables.
Example using SBCL:
a file with
(defun test (foo)
(+ foo foo))
Now we do:
CL-USER> (proclaim '(optimize (debug 0))) ; the compiler saves no debug info
; No value
CL-USER> (compile-file "/tmp/test.lisp")
; compiling file "/private/tmp/test.lisp" (written 23 MAY 2017 09:06:51 PM):
; compiling (DEFUN TEST ...)
; /tmp/test.fasl written
; compilation finished in 0:00:00.013
#P"/private/tmp/test.fasl"
NIL
NIL
CL-USER> (find-symbol "FOO")
FOO
:INTERNAL
The compiler has read the source code and created a compiled FASL file. We see that the symbol FOO is now in the current package. FOO names the variable in our source code.
Now quit SBCL and restart it.
Let's load the machine code:
CL-USER> (load "/tmp/test")
T
CL-USER> (find-symbol "FOO")
NIL
NIL
There is no symbol FOO anymore. It's also not possible to retrieve the lexical value of the variable FOO using the symbol FOO. There is no mapping (like some kind of explicit lexical environment) from symbols to lexical values.
The value cell is used for dynamic (AKA "special") variables, not lexical variables. Lexical variables are symbols in the source code, but they don't have any runtime relationship to the symbol (except for internal use by the debugger).
So if you wrote:
(let ((a 42))
(declare (special a))
(print (symbol-value 'a)))
it would work because the declaration makes it a dynamic variable, and then you can access the value in the function cell.
You are not checking the type of the bound variable a or its value but that of a literal constant symbol that happens to have the same name as the variable in your let form:
(let ((a 42))
(type-of 'literal-symbol))
; ==> symbol (since 'literal-symbol evaluates to a symbol, just like 'a does)
To check the type of the value of the binding a you do it without the literal quote:
(let ((a 42))
(type-of a))
; ==> (integer 0 281474976710655)
Here you actually check the type of the let bound value and it's an integer. Surprised that 42 is a number and not a symbol?
(let ((a 10) (b 'a))
(list a b))
; ==> (10 a)
The variable a and the quoted literal 'a are not the same. They just happen to look the same when displayed but 'a is data and a is code. In CL a compiler might use lists and symbols internally but what it is when its executing is entirely up to the implementation and in most implementations they stack allocate when they can and the code that evaluate a stack allocated variable would be replaced by something that picks the value at the index from the stack. CL has a disassemble function and if you check the output in SBCL from something you'll see it's more similar to the output of a C compiler than the original lisp source.
I use packages a lot and the exported symbols often change their names. When I try to recompile the package I get warnings like this:
package.lisp:3:1:
warning:
MY-PROJECT also exports the following symbols:
(OLD-SYMBOL1 OLD-SYMBOL2 OLD-SYMBOL3)
See also:
Common Lisp Hyperspec, DEFPACKAGE [:macro]
SBCL Manual, *ON-PACKAGE-VARIANCE* [:variable]
--> EVAL-WHEN
==>
(SB-IMPL::%DEFPACKAGE "MY-PACKAGE" '("KE") 'NIL 'NIL 'NIL '("CL") 'NIL
'NIL '("NEW-EXPORTED-SYMBOL1" "NEW-EXPORTED-SYMBOL2") '("MY-PROJECT") 'NIL
...)
I know that I can use (unintern 'old-symbol1) to signal the system I don't want to use that symbol anymore. However this is becoming very tedious when there is a lot of renaming.
My questions are:
1) Is is possible to signal to sbcl or emacs to unintern the old/previously exported symbols automatically?
2) If not - is it possible to get all "old" symbols in a variable?
My plan for 2) is to make a key binding to something like (apply #'unintern *old-symbols*)
Setting the variable *on-package-variance* to a list (:error t) will give you an error instead of a warning when redefining the package. The error will have a restart DROP-THEM to unexport the symbols.
You can add
(setf *on-package-variance* '(:error t))
to your ~/.sbclrc to have it always set when starting up SBCL.
First I don't think you want to unitern symbols. Unintern removes them from the package. I think you want to unexport them to avoid the warning. You can do that with the following function
(defun unexport-package-symbols (package)
(do-symbols (symbol package)
(destructuring-bind (symbol status)
(find-symbol (symbol-name symbol) package)
(when (eq status :external)
(cl:unexport symbol package)))))
;; It takes a package-designator as an argument.
(unexport-package-symbols "MY-PACKAGE")
In a Common Lisp program, I want to find a way to generate a new symbol that is not in use in the program at the time. I am aware of the (gensym) function, but this makes symbols that may already be present in the program. I have some understanding that I need to intern the symbol, so I tried this:
(defun new-symbol () (intern (symbol-name (gensym))))
Which seems to get halfway to the answer. For instance,
[1]> (new-symbol)
G3069
NIL
[2]> (new-symbol)
G3070
NIL
[3]> (defvar a 'G3071)
A
[4]> (new-symbol)
G3071
:INTERNAL
As you can see, the function seems to recognize that the symbol 'G3071' is already in use elsewhere, but I don't know how to get it to generate a new symbol if that is the case.
I am aware of the (gensym) function, but this makes symbols that may already be present in the program.
No, it doesn't. It creates symbols that aren't interned in any package. The documentation says (emphasis added):
Function GENSYM
Syntax:
gensym &optional x ⇒ new-symbol
Arguments and Values:
x—a string or a non-negative integer. Complicated defaulting
behavior; see below.
new-symbol—a fresh, uninterned symbol.
You can also use make-symbol to create a symbol that's not interned in any package. It's documentation summary (pretty much identical to gensym's):
Function MAKE-SYMBOL
Syntax:
make-symbol name ⇒ new-symbol
Arguments and Values:
name—a string.
new-symbol—a fresh, uninterned symbol.
Regarding your second point:
I have some understanding that I need to intern the symbol, so I tried this:
No, if you want a fresh symbol, then you probably don't want to be interning anywhere. Interning is the process whereby you take a string (not a symbol) and get the symbol with the given name within a particular package. If you call intern with the same symbol name and package twice, you'll get back the same symbol, which is what you're trying to avoid.
CL-USER> (defparameter *a* (intern "A"))
*A*
CL-USER> (eq *a* (intern "A"))
T
Since gensym generates the name of the fresh symbol using *gensym-counter*, if you take the name from the gensym symbol and intern it somewhere, you could get the same symbol if someone modifies the value of *gensym-counter*. E.g.:
(let ((counter *gensym-counter*) ; save counter value
(s1 (gensym))) ; create a gensym (s1)
(setf *gensym-counter* counter) ; reset counter value
(let ((s2 (gensym))) ; create a gensym (s2)
(list s1
s2
(eq s1 s2)
(symbol-name s1)
(symbol-name s2)
(string= (symbol-name s1)
(symbol-name s2)))))
; (#:G1037 #:G1037 NIL ; different symbols
; "G1037" "G1037" T) ; same name
I thought I would be able to find this through Google, SO, or the books I'm reading, but it is proving elusive.
In the implementation I'm learning with, I can do the following at the top-level:
(defvar *foo* 4)
(set 'bar 3)
If I then call (describe '*foo*) and (describe 'bar), I get a description saying that *foo* is special and bar is non-special (among other details).
Is there a function that takes a symbol variable as an argument and returns true or false if it is special? If so, is describe probably implemented in part by calling it?
Context: I'm learning Common Lisp, but at work I have a system with a dialect of Lisp similar to Common Lisp, but the describe function is unimplemented. There's sort of an XY thing going on here, but I'm also trying to grok Lisp and CL.
Many Common Lisp implementations provide the function variable-information in some system dependent package.
Here in SBCL:
* (require :sb-cltl2)
NIL
* (sb-cltl2:variable-information '*standard-output*)
:SPECIAL
NIL
((TYPE . STREAM))
This function was proposed as part of some other functionality to be included into ANSI CL, but didn't make it into the standard. Still many implementations have it. For documentation see: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html
A non-special variable's environment will be captured when you create a closure over it:
(let ((x 1))
(let ((f (lambda () x)))
(let ((x 2))
(eql 2 (funcall f)))))
;;=> NIL
A special variable's lexical environment will not:
(defvar *x*) ; *x* is special
(let ((*x* 1))
(let ((f (lambda () *x*)))
(let ((*x* 2))
(eql 2 (funcall f)))))
;;=> T
Using this approach, you could easily define a macro that will expand to code like the previous that will let you determine whether a symbol is globally proclaimed special:
(defmacro specialp (symbol)
(let ((f (gensym "FUNC-")))
`(let ((,symbol 1))
(let ((,f (lambda () ,symbol)))
(let ((,symbol 2))
(eql 2 (funcall ,f)))))))
(specialp x) ;=> NIL
(specialp *x*) ;=> T
Note that this isn't a function, it's a macro. That means that the macro function for specialp is getting called with the symbols X and *X*. This is important, because we have to construct code that uses these symbols. You can't do this with a function, because there'd be no (portable) way to take a symbol and create a lexical environment that has a lexical variable with that name and a lambda function that refers to it.
This also has some risks if you try to use it with certain symbols. For instance, in SBCL, if you try to bind, e.g., *standard-output* to something that isn't a stream or a stream designator, you'll get an error:
CL-USER> (specialp *standard-output*)
; in: SPECIALP *STANDARD-OUTPUT*
; (LET ((*STANDARD-OUTPUT* 1))
; (LET ((#:FUNC-1038 (LAMBDA # *STANDARD-OUTPUT*)))
; (LET ((*STANDARD-OUTPUT* 2))
; (EQL 2 (FUNCALL #:FUNC-1038)))))
;
; caught WARNING:
; Constant 1 conflicts with its asserted type STREAM.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
Defining globals with set or setq is not supported. There are 2 common ways to define globals:
(defparameter *par* 20) ; notice the earmuffs in the name!
(defvar *var* 30) ; notice the earmuffs in the name!
All global variables are special. Lexically scoped variables (not special) are not possible to get described. E.g.
(let ((x 10))
(describe 'x)) ; ==> X is the symbol X
It describes not the lexical variable but the symbol representation. It really doesn't matter since you probably never need to know in run time since you know this when you're writing if it's a bound lexical variable or global special by conforming to the earmuffs naming convention for global variables.
I believe the only way to get this information at run time* is by either using an extension to CL, as Rainer noted, or to use eval.
(defun specialp (x)
(or (boundp x)
(eval `(let (,x)
(declare (ignorable ,x))
(boundp ',x)))))
(Defect warning: If the variable is unbound but declared to be a type incompatible with nil, this could raise an error. Thanks Joshua for pointing it out in his answer.)
* The macro approach determines which symbol it is checking at macro expansion time, and whether that symbol is lexical or special at compile time. That's fine for checking the status of a variable at the repl. If you wanted to e.g. print all of the special variables exported by a package, though, you would find that to use the macro version you would end up having to use eval at the call site:
(loop for s being the external-symbols of :cl-ppcre
when (eval `(specialp-macro ,s)) do (print s))