我最近读了“黑客与画家”这本书。作者说,Lisp宏比其他语言的宏更强大、更特殊。
我开始学习ELisp的宏,但还是不知道它有什么特别的用法?看不出它和C/C++宏有什么不同。
有人能给我解释一下吗?
发布于 2012-05-11 01:52:08
我认为最重要的几点是:
gensym和围绕它构建的抽象(如with-gensyms等),也有卫生的宏系统,主要用于方案中。Lisp语言中的表达式是一种非常方便的填空方法,可以构建宏扩展到的代码。总而言之,使用Lisp宏进行元编程要比使用C/C++预处理器的方法方便得多。在实践中,这意味着即使是Lisp的新手,也能够毫不费力地构建自己的循环构造或其他控制结构。有了更多的经验,编写更复杂的DSL也变得相对容易。这与C/C++预处理器相比,在C/C++预处理器中,这些任务可能被认为是某种黑魔法,只为最勇敢的人保留。
作为一个快速示例,尝试使用C/C++预处理器编写类似以下内容的代码:
(defmacro bif ((var expression) then &optional else)
`(let ((,var ,expression))
(if ,var ,then ,else)))它引入了一个新的控制结构bif ("binding if"),该结构对表达式求值,将其绑定到给定的符号,然后有条件地执行then或else分支,其中绑定在作用域中。它可以正确地嵌套,并按预期工作。现在,任何称职的Lisp程序员都可以很快地编写出这样的东西。因为它很简单,当Lisp程序员感觉到需要一个新的结构时,他们通常会毫不犹豫--语言设计者和语言使用者之间的障碍变得模糊了。
(即使使用C/C++预处理器编写,下一步,也就是编写类似Lisp的cond或新的循环结构,很快就会变得更加复杂。)
发布于 2012-05-10 22:39:05
Lisp宏使用户可以在比C++宏更深的级别上修改语言。Lisp宏是在编译阶段执行的代码片段,它们可以控制参数的计算。
例如,Lisp基于编译器必须处理的大约25种“特殊形式”。Lisp的其余部分可以在这些特殊形式的基础上迭代生成。我不太熟悉ELisp,但是Common Lisp loop功能是通过一个宏实现的。您可以扩展该语言--通常Lisp只有一种特殊的条件形式,而所有其他的都是在Lisp中实现的,在该形式之上。defun是用来定义函数的结构,我相信它可以作为宏来实现。
虽然功能强大,但C++宏是由预处理器执行的,这意味着它们的功能是有限的。因为Lisp宏是在编译环境中执行的,所以它们可以执行函数来确定如何重写它们的输入,包括程序员定义的函数。
这个回答相当复杂和模糊,所以希望有更多时间的人能提供一个更好的答案。我像Pascal一样道歉,因为我把这个答案写得冗长而含糊。
https://stackoverflow.com/questions/10535684
复制相似问题