In Common Lisp, given that "a" is simply a character, what is the difference between #\a
, 'a
#'a
?
My question comes from the tutorialspoint.com tutorial on Lisp. At one point the tutorial introduces:
; a character array with all initial elements set to a
; is a string actually
(write(make-array 10 :element-type 'character :initial-element #\a))
(terpri)
; a two dimensional array with initial values a
(setq myarray (make-array '(2 2) :initial-element 'a :adjustable t))
(write myarray)
(terpri)
With the output:
"aaaaaaaaaa"
#2A((A A) (A A))
#'
is not included in this example but I'm including it in the question because it can be confusing as well. 🙂
Thank you very much! 😊
To start, a
is not "simply a character." The Lisp reader parses #\a
as the character literal a
, which is an object in Common Lisp. Note that #\a
and #\A
are different character objects.
When the Lisp reader encounters a single quote, the expression following the single quote is not evaluated. Specifically, 'a
is treated as (quote a)
, where quote
returns its argument unevaluated. Now, a
is a symbol, so 'a
evaluates to that symbol. But the Lisp reader upcases most characters it reads by default, so 'a
really evaluates to the symbol A
. The good news is that whether you type a
or A
, the Lisp reader will read A
(unless you mess with the readtable), and both 'a
and 'A
evaluate to the symbol A
.
When the Lisp reader encounters #'a
, the entire expression is treated as (function a)
, which when evaluated returns the function associated with the name a
. But, note that it is an error to use function
, and by extension #'
, on an identifier that does not denote a function.
To clarify this last part a bit, consider the following REPL interaction:
CL-USER> (defvar a 1)
A
CL-USER> a
1
CL-USER> #'a
The function COMMON-LISP-USER::A is undefined.
[Condition of type UNDEFINED-FUNCTION]
Here the variable a
is defined and given the value 1
, but when we try to access the function denoted by a
we get an error message because there is no such function. Continuing:
; Evaluation aborted on #<UNDEFINED-FUNCTION A {1002DDC303}>.
CL-USER> (defun a (x) x)
A
CL-USER> (a 'b)
B
CL-USER> a
1
CL-USER> #'a
#<FUNCTION A>
Now we have defined a function named a
that simply returns its argument. You can see that when we call a
with an argument 'b
we get the expected result: (a 'b)
--> b
. But, then when we evaluate a
alone we still get 1
. Symbols in Common Lisp are objects that have, among other cells, value cells and function cells. After the above interaction, the symbol a
now has 1
in its value cell, and it has the function we have defined in its function cell. When the symbol a
is evaluated the value cell is accessed, but when (function a)
or #'a
is evaluated, the function cell is accessed. You can see above that when #'a
is evaluated, the function we defined is returned, and the REPL prints #<FUNCTION A>
to show this.
As an aside, I wouldn't recommend using Tutorialspoint to learn Common Lisp. Glancing over the site, right away I see this:
LISP expressions are case-insensitive, cos 45 or COS 45 are same.
This is just wrong. And, Lisp is not written in all-caps. None of this inspires faith. Instead, find a good book. There are some recommendations on the common-lisp tag-info page.