emacs - 为什么在 Lisp 中将代码视为数据很有用

标签 emacs macros lisp eval homoiconicity

我现在学习 emacs lisp,我想知道为什么将代码视为数据可能有用。这种方法有什么好处。我看到了一种解释,因为这是传统的冯诺依曼架构的替代方案,其中数据和代码之间存在明确的分离。 我想了解这个决定的意义,明白了。

预先感谢,尼克。

最佳答案

您可以编写代码,该代码将为您编写代码。这可以通过两种方式完成:

  • 首先,您的程序可以将新代码创建为列表并将其传递给 eval 函数,该函数将在运行时评估新代码(但是,eval 是你不应该滥用——实际上,当你真正需要它时,应该很少使用它)。理论上,您可以在不具有同像性属性的语言中执行此操作,但这会困难得多。 例如,在Scheme中你可以这样做
(define form '(x 10))
(set! form (append 'define form)
(eval form (interaction-environment)

之后x的值将是10。例如,这可以用在 Genetic Programming 中。

  • 您还可以定义宏。宏是一个小函数,它读取的内容看起来像函数调用,但在程序开始评估表单之前被翻译(扩展)为其他内容(即,之前)它已运行)。例如,在许多 Lisp 中 or 是一个宏。这段代码,
(or a b c)

翻译成

(let ((tmp1 a))
  (if tmp1
      tmp1
      (let ((tmp2 b))
        (if tmp2
            tmp2
            (let ((tmp3 c))
              (if tmp3
                  tmp3
                  #f))))))

您可以将实现为函数,但该函数必须在返回之前评估其所有参数。由于 or 是一个宏,因此它不一定会计算所有参数。

您可以阅读有关宏的更多信息 in Wikipedia并在 this cool book [除了网络上的其他几个地方,例如 here , herehere例如 ]。您可以阅读有关 eval in Wikipedia 的内容并在 this great book .

您还可以阅读 Paul Graham 的 On Lisp (这本书是完全免费的),以比较快的速度教授基础的Common Lisp,然后进入各种宏的编程技术,稍后你可以尝试Let Over Lambda (只有部分章节是免费的)。

关于eval,阅读 this question 可能会很有趣及其答案。

关于emacs - 为什么在 Lisp 中将代码视为数据很有用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25501020/

相关文章:

macos - 如何在 sublime text 2 中录制宏?

c - 为什么在使用函数和宏时会得到不同的结果?

scheme - 从方案中的列表中打印对

lisp - 一般来说, "lexical and special variable"语义是如何在幕后实现的?

emacs - 有没有办法重置 Emacs 键盘映射?

emacs - 如何使 .emacs 文件具有幂等性?

git - 如何恢复 `magit` 中旧提交的更改?

emacs - emacs中框架和窗口之间的差异

c - 使用宏时出错

printing - 输入字符串并将其打印回来的程序将不起作用