From: fix on
Hi all,

I am writing a program to take derivative of a function and evaluate if
given a value.

"deriv" is the function to do symbolic derivatives, the signiture is
defun deriv (expr var)
and the function take derivative of expr with respect to var.
so if I do
(deriv '(* x x) 'x), it returns (+ x x). (Same as 2x, but it doesn't
matter.)

And I want (deriv-eval '(* x x) 'x 5) to return 10.

This is what I have written for deriv-eval:
(defun deriv-eval (expr var val)
(setf derivans (deriv expr var))
(setf var val)
(eval derivans)
)

But it doesn't work for the last line, here is the error:
Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable X is unbound.
[Condition of type UNBOUND-VARIABLE]

I was thinking of, in the first line, get the answer, then give the
variable a value, and evaulate. Am I wrong?

Thanks.
fix.

From: David Sletten on
fix wrote:

> Hi all,
>
> I am writing a program to take derivative of a function and evaluate if
> given a value.
>
> "deriv" is the function to do symbolic derivatives, the signiture is
> defun deriv (expr var)
> and the function take derivative of expr with respect to var.
> so if I do
> (deriv '(* x x) 'x), it returns (+ x x). (Same as 2x, but it doesn't
> matter.)
>
> And I want (deriv-eval '(* x x) 'x 5) to return 10.
>
> This is what I have written for deriv-eval:
> (defun deriv-eval (expr var val)
> (setf derivans (deriv expr var))
> (setf var val)
> (eval derivans)
> )
>
> But it doesn't work for the last line, here is the error:
> Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable X is unbound.
> [Condition of type UNBOUND-VARIABLE]
>
> I was thinking of, in the first line, get the answer, then give the
> variable a value, and evaulate. Am I wrong?
>
> Thanks.
> fix.
>

You misunderstand the macro SETF. However, you should be able to see
that something is wrong just by looking closely at your code. First, you
use SETF to assign a value to a variable named DERIVANS. In other words,
you expect SETF to directly use the symbol you provide it to name a
variable. In the second case you are trying to use SETF to assign a
value not to the variable named VAR but rather to the symbol that VAR
refers to. Clearly this is an inconsistency--SETF can't possibly know
that you intend indirection in one case but not the other.

SETF does not evaluate its first argument, which identifies the 'place'
where it is to store the value of the second argument. Here, to indicate
that the place is the global variable named by VAR's value, you should
use SYMBOL-VALUE. Furthermore, it is better to create a local variable
DERIVANS using LET rather than relying on another global variable:
(defun deriv-eval (expr var val)
(let ((derivans (deriv expr var)))
(setf (symbol-value var) val)
(eval derivans)))

David Sletten
From: Kalle Olavi Niemitalo on
fix <fix(a)tamu.edu> writes:

> And I want (deriv-eval '(* x x) 'x 5) to return 10.

I think you mean 25. Here are a few ways to do it.

(defun deriv-eval (form variable value)
(eval `(let ((,variable ',value)) ,form)))

(defun deriv-eval (form variable value)
(funcall (coerce `(lambda (,variable) ,form) 'function)
value))

If you need to evaluate the expression with multiple different
values for the variable (e.g. for a graph), you can modify the
latter definition to generate the function just once, hopefully
speeding up the process. You could also COMPILE the function at
runtime, although that may actually be slower if you then call it
just a few times.

> (defun deriv-eval (expr var val)
> (setf derivans (deriv expr var))
> (setf var val)

Suppose the value of VAR is X, and the value of VAL is 5. Then,
this (setf var val) will just set VAR to 5, rather than modify X
in any way. (setf (symbol-value var) val) would be closer to
what you need, but it has two problems:

1. The changed value persists even after the function returns, so
it can cause errors if some other part of the program is using
the variable X for another purpose.

2. I think, in principle, the form evaluated with EVAL should
explicitly declare any special variables it uses. However,
the dictionary entry for EVAL says SYMBOL-VALUE is equivalent
to it, so I'm not sure the declarations are required in this
context.

You could fix the first problem with (progv `(,var) `(,val) ...) and
the second with (eval `(locally (declare (special ,var)) ,expr)),
but that's so much typing that you could as well use one of the
lexical-variable solutions I showed above.
From: fix on


David Sletten wrote:
> fix wrote:
>
>> Hi all,
>>
>> I am writing a program to take derivative of a function and evaluate
>> if given a value.
>>
>> "deriv" is the function to do symbolic derivatives, the signiture is
>> defun deriv (expr var)
>> and the function take derivative of expr with respect to var.
>> so if I do
>> (deriv '(* x x) 'x), it returns (+ x x). (Same as 2x, but it doesn't
>> matter.)
>>
>> And I want (deriv-eval '(* x x) 'x 5) to return 10.
>>
>> This is what I have written for deriv-eval:
>> (defun deriv-eval (expr var val)
>> (setf derivans (deriv expr var))
>> (setf var val)
>> (eval derivans)
>> )
>>
>> But it doesn't work for the last line, here is the error:
>> Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable X is
>> unbound.
>> [Condition of type UNBOUND-VARIABLE]
>>
>> I was thinking of, in the first line, get the answer, then give the
>> variable a value, and evaulate. Am I wrong?
>>
>> Thanks.
>> fix.
>>
>
> You misunderstand the macro SETF. However, you should be able to see
> that something is wrong just by looking closely at your code. First, you
> use SETF to assign a value to a variable named DERIVANS. In other words,
> you expect SETF to directly use the symbol you provide it to name a
> variable. In the second case you are trying to use SETF to assign a
> value not to the variable named VAR but rather to the symbol that VAR
> refers to. Clearly this is an inconsistency--SETF can't possibly know
> that you intend indirection in one case but not the other.
>
> SETF does not evaluate its first argument, which identifies the 'place'
> where it is to store the value of the second argument. Here, to indicate
> that the place is the global variable named by VAR's value, you should
> use SYMBOL-VALUE. Furthermore, it is better to create a local variable
> DERIVANS using LET rather than relying on another global variable:
> (defun deriv-eval (expr var val)
> (let ((derivans (deriv expr var)))
> (setf (symbol-value var) val)
> (eval derivans)))
>
> David Sletten

I got it. Thanks so much. But is there any website that has all the
built-in function of LISP? I am actually using LISP in an AI course, but
neither the prof nor the textbook talk much about LISP. Or should I go
get another book? Thanks!

fix.

From: David Sletten on
fix wrote:


>> (defun deriv-eval (expr var val)
>> (let ((derivans (deriv expr var)))
>> (setf (symbol-value var) val)
>> (eval derivans)))
>>

This could be even simpler:
(defun deriv-eval (expr var val)
(setf (symbol-value var) val)
(eval (deriv expr val)))

> I got it. Thanks so much. But is there any website that has all the
> built-in function of LISP? I am actually using LISP in an AI course, but
> neither the prof nor the textbook talk much about LISP. Or should I go
> get another book? Thanks!
>

Your one-stop reference is the Common Lisp HyperSpec:
http://www.lispworks.com/documentation/HyperSpec/Front/index.htm

If you would like to read a helpful text:
http://www.gigamonkeys.com/book/

David Sletten
 |  Next  |  Last
Pages: 1 2 3
Next: Fas->Lsp Decompiler Project