在Lisp中,+;功能究竟有哪些?

在Lisp中,+;功能究竟有哪些?,lisp,common-lisp,Lisp,Common Lisp,我对Lisp比较陌生,我想知道“+”函数是否真的有上限 (我想这适用于所有其他算术函数“-”、“/”等)简单回答是否定的,尽管使用递归而不是尾部递归的糟糕实现会有堆栈限制 根据您的实现情况,+可以使用递归或直接函数调用来实现 我对Common Lisp不太了解,不知道它指定了什么要求,但大多数实现,如果使用递归,将使用尾部递归,并避免任何堆栈限制 函数调用将能够以列表的形式访问参数,因此可以处理的参数数量没有限制 编辑:由于有人实际给出了一个公共Lisp引用,显然这应该是一个更好的答案,但我认为

我对Lisp比较陌生,我想知道“+”函数是否真的有上限


(我想这适用于所有其他算术函数“-”、“/”等)

简单回答是否定的,尽管使用递归而不是尾部递归的糟糕实现会有堆栈限制

根据您的实现情况,+可以使用递归或直接函数调用来实现

我对Common Lisp不太了解,不知道它指定了什么要求,但大多数实现,如果使用递归,将使用尾部递归,并避免任何堆栈限制

函数调用将能够以列表的形式访问参数,因此可以处理的参数数量没有限制


编辑:由于有人实际给出了一个公共Lisp引用,显然这应该是一个更好的答案,但我认为任何好的实现都会在提供足够的参数时自动应用等价的
(reduce#'+arg list)

是的,有一个上限,但确切的上限取决于实现。你保证至少能通过50级考试,但这要看情况而定。如果需要对列表求和,最好使用
(reduce#'+list)
,这应该比任何其他方法都具有更好的可伸缩性

有更多的信息


当涉及到值范围时,有两种不同的情况,浮点和整数。浮点数本质上受到其大小的限制,而一个从单浮点数变为双浮点数的实现会让我大吃一惊。对于整数和有理数,CL在fixnums和bignums之间无缝转换,因此限制是实现可用地址空间的函数。我怀疑复数也是如此(复数和有理数->必要时转到bignums;复数浮点数->发出超出范围的信号,或返回Inf或NaN)。

通用Lisp的定义方式可以有效地在各种硬件和软件系统上实现。例如,摩托罗拉68000/20/30/40等处理器、各种英特尔x86处理器、基于Lisp机器堆栈的处理器、DEC VAX、RISC处理器、克雷等超级计算机。在80年代,有很多处理器家族在竞争,包括为执行Lisp代码而开发的处理器。今天,我们仍然有几个处理器系列(x86、x86-64、ARM、SPARC、POWER、PowerPC等)

它也可以编译成C、Scheme或其他编程语言

它还可以被编译成虚拟机,如CMUCL、CLISP或JVM/Java虚拟机(Java虚拟机似乎有254个参数的限制)

例如,一个普通的Lisp编译器可能会将Lisp代码编译成直接的C代码。因此,如果尽可能多地重用C编译器的函数调用就好了。特别是为了使从C调用Lisp更容易

C/C++在这方面也有限制:

给出了C++的127(C)和256的数值。因此,对于Lisp到C编译器来说,这些可能是限制。否则Lisp代码将不会使用C函数调用

第一个这样的编译器KCL(Kyoto Common Lisp,后来这个实现演变成GCL/GNU Common Lisp和ECL/Embeddeble Common Lisp)的调用参数限制为64

例如,LispWorks/Mac OS X的64位实现的
CALL-ARGUMENTS-LIMIT
值为2047

CALL-ARGUMENTS-LIMIT
不得小于50


因此,在公共Lisp中,列表处理和调用参数是不相关的。如果要处理列表,必须使用列表处理工具(list、MAPCAR、APPEND、REDUCE等)。Common Lisp提供了一种使用
&REST
参数以列表形式访问参数的机制。但通常应该避免这种情况,因为它可能会导致函数调用开销,因为需要使用参数列表。

Clojure提供了一个Lisp示例,在该示例中,通过使用惰性序列,函数实际上可以有无限多个参数:

; infinite lazy sequence of natural numbers
(def naturals (iterate inc 1))

(take 10 naturals)
=> (1 2 3 4 5 6 7 8 9 10)

; add up all the natural numbers 
(apply + naturals)
=> ...... [doesn't terminate]

当然不是特别有用….

这取决于实现。“我建议LISP用户花5分钟测试他们的平台”

为Clojure

(defn find-max-n [n]
  (try 
    (eval (concat (list +) (take n (repeat 1))))
    (println "more than" n)
    ; return n if something goes wrong
    (catch Exception e n))
  (recur (* n 2)))


(find-max-n 1)
它没有终止,根据我的设置,它挂起在8192

more than 1
more than 2
more than 4
more than 8
more than 16
more than 32
more than 64
more than 128
more than 256
more than 512
more than 1024
more than 2048
more than 4096
more than 8192

常见的Lisp通常不是尾部递归的。我有一种感觉,我读到有一个原因,为什么他们不被允许进行尾部调用优化(尽管,我很可能是这么想的)。而且,没有理由为什么实现会使用递归,考虑到
reduce
loop
@Marcin的可用性,如果您调整优化变量(主要是“速度”高和“调试”低,但具体请参见您的实现手册),它们可以进行尾部调用优化,而大多数都可以进行优化。我会假设
+
的实现方式与您建议的方式大致相同。@Marcin:因为它有一个上限,所以它不是任意的。这是规范所说的,但是您知道有任何实际实施限制的实现吗?@Marcin很好,SBCL保证调用参数限制在10^18的范围内,我希望传递更多根本不起作用的参数。我手头没有任何其他的实现,但我确实记得有人在使用APPLY而不是REDUCE时遇到问题,列表很短,如“在数百个元素中”。@Vatine我刚刚意识到我的标题和问题描述在其预期含义上相互矛盾。既然我认为你回答的是“+”函数的值限制,你介意评论一下该函数可以拥有的输入限制吗?抱歉搞混了@联盟号我很确定他说的是输入的数量。@Soyuz I