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
函数。
REV:OUT
绑定到 NIL
,IN
绑定到列表 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 函数的主要内容,如果未能解决你的问题,请参考以下文章
python中的 list.reverse()和reversed()