[我遇到了一个问题,即我有了一个宏,等熵扩展,然后调用'-?'替换列表中的NIL的solve-format格式,然后可以传递有效的表达式来求解。
(isentropic-expansion 295 nil 1 4.2 1.4)
返回
(-
(expt
(/ 4.2 1)
(/
(- 1.4 1)
1.4))
(/ x\? 295))
这是要放入solve函数的有效表达式
但是如果我执行以下操作(假设我已经将上述命令的输出设置为变量expr
(solve expr 2)
宏不将表达式符号替换为expr的值,仅对字符串进行expr,然后得到
Wrong number of arguments: (lambda nil expr), 1
我认为这是因为我还没有完全理解宏!谁能解释为什么这样吗?
(defun newton-f (func x0)
"Solve the equation FUNC(x)=0 using Newton's method.
X0 is an initial guess."
(let* ((tolerance 1e-6)
(x x0)
(dx 1e-6)
fx fpx)
(while (> (abs (funcall func x)) tolerance)
(setq fx (funcall func x)
fpx (/ (- (funcall func (+ x dx)) (funcall func (- x dx))) (* 2 dx))
x (- x (/ fx fpx))))
x))
(defmacro solve (expression guess)
`(newton-f
(lambda ,(cl-loop for item in (flatten expression)
if (and (symbolp item) (s-ends-with? "?" (symbol-name item)))
collect item)
,expression)
,guess))
(defun solve-format (exp)
(cond ((null exp) 'x?)
((atom exp) exp)
((list exp) (cons (solve-format (car exp))
(if (cdr exp)
(solve-format (cdr exp))
nil)))
(t (print "what"))))
(defmacro isentropic-expansion (t01 t02 p01 p02 gamma)
`(solve-format '(- (expt (/ ,p02 ,p01) (/ (- ,gamma 1) ,gamma)) (/ ,t02 ,t01))))
solve
也是宏:
(defmacro solve (expression guess) ...)
由于使用此宏,宏不会自动evaluate其参数:
(solve expr 2)
在宏扩展期间,其expression
绑定到符号expr
,guess
绑定到数字2
。
错误消息中的(lambda nil expr)
是此调用:
(lambda ,(cl-loop for item in (flatten expression)
if (and (symbolp item) (s-ends-with? "?" (symbol-name item)))
collect item)
,expression)