![]() |
1
6
口齿不清 homoiconic . 下面是一个函数,它构建一个表示和的s表达式。
所以
使用Lisp宏有更复杂的示例。另见
this
. 阅读关于
Evaluation and Compilation
共同的Lisp HyperSpec
我强烈推荐阅读 SICP (可以免费下载)然后 Lisp In Small Pieces . 你也可以享受阅读 Gödel, Escher, Bach.... 和J.Pitrat的博客 Bootstrapping Artificial Intelligence . 顺便说一下,在POSIX上使用C,您还可以编写程序 generating C代码(或使用 GCCJIT 或 LLVM ),将生成的代码编译为插件,然后 dlopen -正在使用它。 |
![]() |
2
2
虽然同质性是使这一点变得简单的基本属性,但在实践中,这一点的一个很好的例子是许多lisp中存在的宏功能。同象性允许您编写使用lisp源(表示为列表列表)的lisp函数,并对其执行列表操作操作以生成其他lisp源。宏是一个简单的lisp函数,它作为语言语法的扩展安装在lisp的编译器/求值器中。宏像普通函数一样被调用,但是编译器没有等到运行时才将宏参数的原始代码传递给它。然后宏负责返回一些替代代码,以便编译器在其位置进行处理。
一个简单的例子是内置的
翻译
尽管我可能会使用列表模板语法和一些较短的函数来获得:
这被称为:
现在我们需要做的就是通知编译器当它看到一个
sorta看起来像一个常规函数,只是它获取代码并输出其他代码。现在我们可以写了
lisp宏工具构成了lisp表达能力的一个主要组成部分——它们允许您对语言进行建模,以更好地适应您的项目,并抽象出几乎所有的样板。宏可以简单到
|
![]() |
3
0
一个很好的例子是Lisp宏。它们不求值,而是转换为其中的表达式。这就是为什么他们本质上是编写程序的程序。它们在编译时和运行时之间转换其中的表达式。这意味着您基本上可以创建自己的语法,因为宏实际上没有求值。一个很好的例子是这个无效的公共lisp表单:
显然,format函数的语法是向后的。但是。。。我们将它传递给一个未计算的宏,因此不会得到回溯错误,因为宏实际上没有计算。以下是宏的外观:
如您所见,我们在宏中反转表达式,这就是为什么它在编译时和运行时之间成为标准的Lisp表单的原因。我们用一个简单的例子从本质上改变了Lisp的语法。对宏的调用不计算,而是转换。一个更复杂的例子是用html创建网页:
我们基本上可以创建一个宏,对该宏的调用将不会被计算,但它将扩展为有效的lisp语法,并且将被计算。如果我们看一下宏扩展,我们可以看到扩展是被计算的:
扩展到:
这就是为什么Paul Graham提到你可以编写程序,而ViaWeb本质上是一个大宏。像这样的一堆宏正在编写可以编写代码的代码。。。 |
![]() |
lightning_missile · 词法范围和共享对象 6 年前 |
![]() |
Alexandru Popa · SBCL中奇怪的宏扩展错误 6 年前 |
![]() |
Jacky · 编辑列表中的每个偶数索引元素 6 年前 |
![]() |
HappyFace · lisp典型缩进约定背后的规则是什么? 6 年前 |
![]() |
Jorge · 在公共Lisp中初始化计数器变量 6 年前 |
![]() |
Rorschach · cl循环破坏性修改cons单元 7 年前 |