首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lisp宏的特殊用法?

问Lisp宏的特殊用法?
EN

Stack Overflow用户
提问于 2012-05-10 22:03:56
回答 2查看 603关注 0票数 3

我最近读了“黑客与画家”这本书。作者说,Lisp宏比其他语言的宏更强大、更特殊。

我开始学习ELisp的宏,但还是不知道它有什么特别的用法?看不出它和C/C++宏有什么不同。

有人能给我解释一下吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-11 01:52:08

我认为最重要的几点是:

  • Lisp代码被表示为列表,通过Lisp宏,您可以使用Lisp的所有列表处理功能(这是Lisp非常适合的功能,记住LISP代表list Processing)来转换它。(同源) C/C++预处理器宏,然而,仅仅是文本替换。也就是说,要执行更复杂的转换,您必须自己解析C/C++预处理器宏的输入(并且您通常无法访问这些语言中的解析器)。您不能使用所有的C/C++或手头的任何语言来转换您的代码。这些简单的宏工具似乎更适合于小缩写(或者绕过类型系统、性能变通等),而不是真正的抽象。(并不是说不能将它们用于更复杂的任务,但很快就会变得一团糟。)
  • Lisp语法也比通常的大括号语言规则得多。你不必担心优先级规则,内缀运算符,或者语句和expressions.
  • In之间的区别与Lisp宏的对比。据我所知,使用C/C++预处理器宏时,你不能在宏定义中轻松地使用宏,因为预处理器只通过一次。
  • 在C/C++风格的预处理器宏中没有简单的方法(据我所知)来引入新的符号。(您可以在CL样式的宏中使用gensym和围绕它构建的抽象(如with-gensyms等),也有卫生的宏系统,主要用于方案中。Lisp语言中的表达式是一种非常方便的填空方法,可以构建宏扩展到的代码。

总而言之,使用Lisp宏进行元编程要比使用C/C++预处理器的方法方便得多。在实践中,这意味着即使是Lisp的新手,也能够毫不费力地构建自己的循环构造或其他控制结构。有了更多的经验,编写更复杂的DSL也变得相对容易。这与C/C++预处理器相比,在C/C++预处理器中,这些任务可能被认为是某种黑魔法,只为最勇敢的人保留。

作为一个快速示例,尝试使用C/C++预处理器编写类似以下内容的代码:

代码语言:javascript
复制
(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或新的循环结构,很快就会变得更加复杂。)

票数 4
EN

Stack Overflow用户

发布于 2012-05-10 22:39:05

Lisp宏使用户可以在比C++宏更深的级别上修改语言。Lisp宏是在编译阶段执行的代码片段,它们可以控制参数的计算。

例如,Lisp基于编译器必须处理的大约25种“特殊形式”。Lisp的其余部分可以在这些特殊形式的基础上迭代生成。我不太熟悉ELisp,但是Common Lisp loop功能是通过一个宏实现的。您可以扩展该语言--通常Lisp只有一种特殊的条件形式,而所有其他的都是在Lisp中实现的,在该形式之上。defun是用来定义函数的结构,我相信它可以作为宏来实现。

虽然功能强大,但C++宏是由预处理器执行的,这意味着它们的功能是有限的。因为Lisp宏是在编译环境中执行的,所以它们可以执行函数来确定如何重写它们的输入,包括程序员定义的函数。

这个回答相当复杂和模糊,所以希望有更多时间的人能提供一个更好的答案。我像Pascal一样道歉,因为我把这个答案写得冗长而含糊。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10535684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档