LISP 中的 REVERSE 函数

Posted

技术标签:

【中文标题】LISP 中的 REVERSE 函数【英文标题】:REVERSE function in LISP 【发布时间】:2013-12-17 10:49:37 【问题描述】:

谁能详细解释以下纯 LISP 函数的工作原理:

(DEFINE (REVERSE (LAMBDA (L)
        (REV NIL L))))
(DEFINE (REV (LAMBDA (OUT IN)
        (COND ((NULL IN) OUT)
        (T (REV (CONS (CAR IN) OUT) (CDR IN))))))

该函数应该颠倒列表中元素的顺序,这很清楚,但我仍然无法理解它是如何工作的。

*编辑*

好的,我相信我想通了。 REVERSE 函数以列表作为参数调用,并以 NIL 和列表 L 作为参数调用 REV 函数。

REVOUT 绑定到 NILIN 绑定到列表 L。 现在,如果第一个参数 (IN) 为空 (NULL?),我们就完成了,我们可以返回 OUT,即列表,成功反转。 否则,我们必须以OUT+the first element of IN 作为第一个参数,rest of IN 作为第二个参数递归调用REV。这是它的工作原理吗?

唯一的问题是:这里的LAMBDA 是怎么回事?

【问题讨论】:

(define (name . args) ...)(define name (lambda args ...))(define (name . ((lambda (l) (rev nil l)))) #| no body |# ) 不起作用。 【参考方案1】:

是的,它就是这样工作的。这被称为用于编写tail recursive 函数的累加器参数技术。它有助于通过一些示例来可视化其操作,例如

reverse [1,2,3,4] 
  = rev  NIL  [1,2,3,4]
  = rev  [1]    [2,3,4]
  = rev  [2,1]    [3,4]
  = rev  [3,2,1]    [4]
  = rev  [4,3,2,1]  NIL
  = [4,3,2,1]

您的代码似乎来自旧的(1982 年第 1 版,ISBN 0-471-08755-6)textbook。在今天的计划中,例如它的写法几乎相同,但没有额外的括号(几乎没有重新定义常量):

(define reverse (lambda (l) .... ))
(define rev (lambda (out in) .... ))

(define NIL '())
(define T    #t)
(define NULL null?)

所谓的“lambda forms”,即以lambda“keyword”开头的表单(格式良好、带括号的sn-ps代码)表示匿名函数。符号lambda 后面的列表指定了此类函数的形式参数。 define 允许我们命名由 lambda 形式创建的函数。这样我们就可以在它的定义中递归调用它,使用它的名字。

这个递归调用在tail position中,所以这个函数的操作相当于一个循环(通过在函数调用中重用stack frame实现,在每次迭代时重置形式参数,从而作为循环变量) .

【讨论】:

那么 lambda 形式是在 LISP 中处理参数的一种方式,对吗? @user1291235 lambda 形式是在 Lisp 中创建函数的一种方式。 计划?使用 NIL 和 T? @uselpa 你是对的。我猜define 让我失望了。那么,它是什么? @uselpa 显然代码是“编程语言概念”的逐字复制。-第三版。Carlo Ghezzi,Mehdi Jazayeri。John Wiley & Sons" (1st.ed.1982),amazon.com/Programming-Language-Concepts-Carlo-Ghezzi/dp/…, p345。作者称这种语言为“Lisp”。

以上是关于LISP 中的 REVERSE 函数的主要内容,如果未能解决你的问题,请参考以下文章

倒置函数reverse的用法

reverse函数:反转容器内容

python中的 list.reverse()和reversed()

js数组中的reverse()方法

从 reverse_iterator 中的用户定义的迭代器继承所有函数

c++ 中reverse函数用法