Lisp中的冗余

4
我已开始学习Lisp,想知道在多种不同的方式下执行特定任务的冗余是否有用?我相信经验丰富的Lisp程序员可以回答这个问题。
举个例子,我们可以通过以下两种不同的方式创建函数。
(defun add2 (x) (+ x 2))

或者

(setf (symbol-function 'add2)
  #'(lambda (x) (+ x 2))

我知道这样做可以提高灵活性以达到不同的目的。但是,为什么要有这些冗余,一个适当的解释可以帮助我更好地理解这些内容。

3个回答

15

第一种形式的存在是因为定义函数是一项非常普遍的任务,你需要方便的语法来完成它。

第二种形式的存在是因为有时候你想要用宏生成函数定义或其他高级操作。

如果没有 defun,我们仍然可以使用第二种形式来定义函数,但是没有人会使用 Lisp 编程,因为一个简单的任务变得非常困难。每个程序员都将设计自己的 defun 宏,而这些宏是不兼容的。


2
如果您查看现有实现中的DEFUN,它不仅仅定义了一个函数。例如,它为IDE(开发环境)记录了定义位置,设置了文档,记录了类型信息等等。
通常,Lisp通过函数接口暴露出一些机制。典型用法是通过一组宏提供方便的界面和开发环境中的副作用。
有时,使用CLOS时,甚至在函数接口下面还有一个面向对象的实现。
这时的情况如下图所示。
macros <- used by the programmer, convenient to use
   ^
   |
functions <- user interface to the implementation
   ^
   |
CLOS (classes, instances, generic functions) <- low-level extensible machine

1

你所描述的基本上是 Lisp 的一个副作用,因为 Lisp 的大部分都是用 Lisp 本身编写的。因此,通常可以使用高级定义和其背后的低级内容都可供程序员使用。

如果想要进行高级操作,否则不可能实现,则可以使用低级定义,这非常方便,但通常可以将其视为实现细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接