[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
A question for DEFUN
Chun-Yu Lee writes:
> I wrote a simple equation solver in LISP (see below). If a function
> that uses the macro "equation" is defined before the file "eqsolver.lsp"
> is loaded, everything seems all right. For example,
Common-Lisp really needs all macros to be defined before they are
used. Not doing so in your first example makes Common-Lisp interpret
the call to EQUATION as a function call. That's not what seem to want.
> However, when the function is defined after, then the result becomes as
> > (defun foo (a b) (equation a = b))
> *** - EVAL: variable B has no value <--- Why does "defun" need to evaluate
> 1. Break> the arguments of a function.
It's not the defun, it's your macro that's calling EVAL several times.
The EQUATION macro can be expanded by Common-Lisp at the time the
defun is supplied, not necessarily when you call the new function.
> ; A symbol name which is unbound or nil in the equation is an unknown.
> ; The macro "symbol-equation" returns three values: the solved expression
> ; in symbolic form, the unknown variable, and the operater. But there is
> ; only one value will be returned, when the unknown cannot be found, to be
> ; true (T) or false (NIL) according to the evaluation of the equation.
I believe that there is some misunderstanding here about the way
macros work. Macros can be used to transform an expression into
another expression, but this is usually only done once, for example
when you include your macro call in a defun. You _can_ write a macro
that analyses your equation and transforms it into another
expression. You _cannot_ write a macro that will solve your equation
in function of the unknown variable, because at macroexpansion time,
you don't know which variable is the unknown variable. You'll only
have this information at run-time (e.g. when you call FOO).
Reread the LISP FAQ: If you think that you need EVAL in a macro, then
you are almost certainly doing something wrong.
Why do you want to use macros anyway? To save you quotes? They are
only needed when testing your functions at top-level.
; > (symbol-equation (* a b) = (+ c 4))
; (- (* A B) 4) ;
; C ;
; > (equation (* a b) = (+ c 4))
; 8 ;
Attention! danger! In Common-Lisp, you'll have to understand and be
very careful about lexical and special variables in order to use
things like SETQ, SYMBOL-VALUE and BOUNDP to get the values of your
expressions or to manipulate values. I'd suggest using your own
binding list. This is easier to keep control of and doesn't interact
with others use of the variables.
(symbol-equation '((* a b) = (+ c 4)) '((a .3) (b . 4))) or
(symbol-equation '((* a b) = (+ c 4)) 'c)
(equation '((* a b) = (+ c 4)) '((a . 3) (b . 4))) or
(equation '((* a b) = (+ c 4)) 'c '((a . 3) (b . 4)))