打印没有评估的函数调用参数,不使用"宏"

时间:2015-12-24 02:03:24

标签: scheme lisp common-lisp

在Lisp中的函数调用期间将评估参数。除了宏之外还有什么方法可以在没有评估的情况下打印参数吗?

以Common Lisp为例:

(defun foo (&rest forms)
  (loop for i in forms collect i))

致电" foo"在REPL toplevel:

CL-USER> (foo (= 1 2) (< 2 3))

得到了结果:

(NIL T)

有没有办法得到这个结果?:

((= 1 2) (< 2 3))

2 个答案:

答案 0 :(得分:8)

如果没有宏,你不能在Scheme或Common Lisp中这样做。当然,使用宏也是非常简单的,所以如果它们适合您的用例,请随意使用它们。

那就是说,这个问题比你预期的要多一些。你正在有效地要求一种已经过时的Lisp中出现的功能,称为fexprs。 fexpr正是你所描述的:一个函数,其操作数被传递给它而不被评估。

大多数现代方言都取消了fexprs而只支持使用宏,你可以看到this Stack Overflow question以获取有关原因的更多信息。要点是,fexprs难以优化,难以推理,并且通常不如宏,因此它们被认为是多余的,并且是有害的并且被立即删除。

一些现代的Lisps仍然支持fexprs或类似的东西,但这些方言与Scheme和CL的相对巨人相比是罕见且不常见的,它们主导着现代Lisp世界。如果你需要这种东西,只需使用宏。更好的是,仅仅quote参数,所以你根本不需要任何宏。你会更明确(因此更清楚),你会得到同样的行为。

答案 1 :(得分:2)

是;你可以使用一个名为quote的运算符来获得结果,如果你不介意再嵌套一层:

(quote ((= 1 2) (< 2 3)))
-> ((1 2) (2 3))

quote不是宏;它是special operator