1
votes

I'm running into the following problem in Common Lisp (using CLISP)... The following code runs just fine and as expected ('->' designates what the function call returns):

(list (quote x)) -> (X)

However, when I try to move this behavior into a function,

(defun quote-it (x) 
    (list (quote x)))

And I call the function, I get an unexpected error.

(quote-it x) -> SYSTEM::READ-EVAL-PRINT: variable X has no value

Can anyone explain what's going on here?

Thanks.

2

2 Answers

4
votes

If you compile quote-it, you will get a warning that you are not using the value of the argument x. This should serve as a, well, warning that something is amiss.

Specifically, Common Lisp evaluates the expression (quote-it x) by, first, evaluating x, and, second, passing the result to quote-it. Since you never gave x a value, the first step fails.

Try these:

(defparameter x 42)
(quote-it x)
==> (x)
(quote-it 'y)
==> (x)

As you can see, it does not matter what you pass to quote-it.

PS: generally speaking, the special operator quote is rarely used in functions. It is a common tool in macros though, as suggested by a commenter:

(defmacro quote-it (x) `(list ',x))

If you tell us what you want to achieve (in a separate question), we (the SO community) might be of more help.

0
votes

First it evaluates (QUOTE-IT X).

For that it evaluates X.

X has no value.

You can easily see this in the backtrace or the stepper:

CLISP Backtrace.

Break 1 [5]> :bt
<1/153> #<SYSTEM-FUNCTION SHOW-STACK> 3
<2/146> #<COMPILED-FUNCTION SYSTEM::PRINT-BACKTRACE>
<3/140> #<COMPILED-FUNCTION SYSTEM::DEBUG-BACKTRACE>
<4/131> #<SYSTEM-FUNCTION SYSTEM::READ-EVAL-PRINT> 2
<5/128> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2-3>
<6/124> #<SYSTEM-FUNCTION SYSTEM::SAME-ENV-AS> 2
<7/110> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2>
<8/108> #<SYSTEM-FUNCTION SYSTEM::DRIVER>
<9/68> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP>
<10/65> #<SYSTEM-FUNCTION INVOKE-DEBUGGER> 1
<11/55> #<SYSTEM-FUNCTION ERROR>
<12/42> #<COMPILED-FUNCTION SYSTEM::CHECK-VALUE>
[39] EVAL frame for form X
[34] EVAL frame for form (QUOTE-IT X)

CLISP stepper

[10]> (step (quote-it x))
step 1 --> (QUOTE-IT X)
Step 1 [11]> :s             ; <--- STEP
step 2 --> X                
Step 2 [12]> :S             ; <--- STEP

*** - EVALHOOK: variable X has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of X.
STORE-VALUE    :R2      Input a new value for X.
ABORT          :R3      Abort main loop