Simple LISP function not working
I decided to learn LISP today, and have been playing around with it for a bit. I wrote a simple baby function just to test my understanding, and now understand that my understanding doesn't understand as much as I had understood it to understand. :D
Anyway, here is the function. The idea is that when it is called, e.g. (esexp base x) it should return the value base^x. So (esexp 3 4) = 3^4 = 81.
(I am using the CMU implementation of Common Lisp, if that matters.)
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ esexp (base (+ x 1)) base)
(* esexp (base (+ x 1)) base))))
This doesn't work. I get errors that look like (Warning: This variable is undefined: SLBEXP) and (Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable SLBEXP is unbound.) So. What am I doing wrong? AND would there be a better (or more LISP-ish way) to write this function?
ETA
Corrected code:
(defun esexp (base x)
(if (= x 0)
1
(if (<开发者_如何学编程; x 0)
(/ (esexp base (+ x 1)) base)
(* (esexp base (- x 1)) base))))
esexp(base (+ x 1))
should be
(esexp base (+ x 1))
esexp
is a function just like +
. The syntax for invoking a function is
(function-name arg1 arg2 ...)
The technical explanation of the error: the compiler was parsing the code:
(/ esexp(base (+ x 1)) base)
as this:
(/ esexp (base (+ x 1)) base)
which says:
- first, add 1 to the parameter
x
- then, invoke a function called
base
with the result above. - divide the value of a variable called
esexp
by the result above. - then, divide that result by the parameter
base
. (The divide operator in Common Lisp can take more than two arguments.)
You see the trick? When a word appears as the first item in a s-expression (and that s-expression isn't quoted), it's usually treated as the name of a function you want to invoke. Otherwise, it's treated as the name of a variable whose value you want to retrieve. Further, in Common Lisp a symbol like esexp
can be bound to both a function value and a variable value at the same time; context or special expressions like #'esexp
(which means the function) are used to figure out which one you mean.
The compiler was telling you that, though esexp
was bound to a function with your defun
statement, it had not yet been bound to a variable value, and therefore could not be used as such. Hence, the error.
Just a note about the code. I believe it should be
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ (esexp(base (+ x 1)) base))
(* (esexp(base (- x 1)) base))))
Otherwise the function will never terminate. (you had (* (esexp(base (+ x 1)) base))))
)
精彩评论