Lisp将评估表达式传递给宏

问题描述 投票:0回答:1

[我遇到了一个问题,即我有了一个宏,等熵扩展,然后调用'-?'替换列表中的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))))
lisp elisp
1个回答
0
投票

solve也是宏:

(defmacro solve (expression guess) ...)

由于使用此宏,宏不会自动evaluate其参数:

(solve expr 2)

在宏扩展期间,其expression绑定到符号exprguess绑定到数字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)
© www.soinside.com 2019 - 2024. All rights reserved.