我已经开始学习Lisp了,并且想知道以几种不同方式完成特定任务的所有冗余是否有用?肯定有经验的Lisp程序员可以回答这个问题。
举一个例子。我们可以通过以下两种不同的方式创建函数。
(defun add2 (x) (+ x 2))
或
(setf (symbol-function 'add2)
#'(lambda (x) (+ x 2))
据我所知,这为实现不同的事情提供了灵活性。但是,为什么拥有所有这些冗余的正确解释可以帮助我更好地理解事物。
答案 0 :(得分:15)
存在第一种形式,因为定义函数是一种常见的杂事,你想要一个方便的语法。
存在第二种形式,因为有时候,你想用宏来生成函数定义等等。
如果没有defun
,我们仍然可以用你的第二种形式定义函数,但是没有人会在Lisp中编程,因为一个简单的任务将是非常艰巨的。每个程序员都会设计自己的defun
宏,与其他宏不兼容。
答案 1 :(得分: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
答案 2 :(得分:1)
您所描述的内容基本上是Lisp的大部分内容本身就是一个副作用。因此,通常都会使用高级定义,并且程序员可以使用它背后的低级别定义。
如果您想要执行本来不可能的高级内容,那么可以使用低级定义非常好,但通常可以将其视为实现细节。