Emacs Lisp中的评估顺序

7

我正在尝试编写一些emacs lisp代码,但是我无法理解以下行为

(defun sq (x) (* x x))

(member 9 '(1 2 3 4 (sq 3)))

这段文字涉及到IT技术,翻译如下:

这个表达式的计算结果是nil,但我期望的值是(9)

我猜*emacs lisp使用应用序求值,那么为什么在函数被应用前列表没有被求值呢?

由于我只需要测试一个非空条件,我最终可以按照以下方式解决问题,

(member 9 (cons (sq 3) '(1 2 3 4)))

这将被解析为(9 1 2 3 4)

我的问题是,这是否有效是因为(sq 3)是函数cons的“直接”参数,而不像之前的例子中它是一个参数内部的元素?在这里使用cons是可接受的解决方法,还是有更好/正确的方法来获得所需的行为?

* 尽管无法确定emacs lisp使用的求值顺序,但我在scheme解释器中尝试了相同的表达式并得到了相同的答案,而且从SICP中我知道scheme使用应用序求值。现在我真的很困惑!

感谢任何帮助。

1个回答

17

问题在于您将列表引用起来,因此它的所有元素都不会被评估,而只会作为字面符号传递。如果您想评估列表的某些元素,同时将其他元素作为字面值传递,最方便的形式是使用反引号,即:

(member 9 `(1 2 3 4 ,(sq 3)))

反引号与正常引号的表现相同,但是前面有逗号的列表元素会被求值,并将求值的结果代替回列表中。

另外,你可以使用list函数,它会评估其参数(除非显式引用):

(member 9 (list 1 2 3 4 (sq 3)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接