在Lisp中,+函数实际上有多少输入?
是的,有一个上限,但确切的上限取决于实现。你保证能够通过至少50次,但这一切都取决于。如果你需要总结一个列表,你最好用(reduce #'+ list)
,这应该会给你一个比任何其他方法更好的可伸缩性。
Common Lisp HyperSpec有更多信息。
当涉及到值范围有两个不同的情况下,浮动和整数。浮游物本身受其尺寸的限制,并且从单浮游物变为双浮游物的实施方式会让我大吃一惊。使用整数和有理数,CL可以在fixnums和bignum之间无缝转换,因此限制是可用于实现的可用地址空间的函数。我怀疑对于复数(复杂整数和有理因素 - >如果需要的话去bignum;复杂浮点数 - >超出范围,或返回Inf或NaN)也是如此。
答案很简单,没有,虽然使用递归而不是尾递归一个贫穷的实施将有一个堆栈限制。
根据您的实现+可能会使用递归或直接函数调用来实现。
我不太了解Common Lisp,知道它指定了什么要求,但是大多数实现(如果它们使用递归)将使用尾递归并避免任何栈限制。
函数调用将能够作为列表访问参数,因此对可以处理的参数数量没有限制。
编辑:因为有人实际上给了一个Common Lisp引用,它显然应该是一个更好的答案,但我会认为当提供足够的参数时,任何好的实现都会自动应用(reduce #'+ arg-list)
的等效。
Common Lisp已被定义为可以在各种硬件和软件系统上有效实现。例如Motorola 68000/20/30/40,各种Intel x86处理器,基于Lisp Machine堆栈的处理器,DEC VAX,RISC处理器,Cray等超级计算机等处理器。在80年代,有许多处理器系列竞争,包括为执行Lisp代码而开发的处理器。今天,我们仍然有几个处理器系列(x86,x86-64,ARM,SPARC,POWER,PowerPC ......)。
它也可以编译为C,Scheme或其他编程语言。它也可以编译为像CMUCL,CLISP或JVM/Java虚拟机的虚拟机(Java虚拟机似乎有254个参数的限制)。
例如,Common Lisp编译器可能会将Lisp代码编译为直接C代码。因此,尽可能多地重用C编译器的函数是很好的。特别是从C调用Lisp更容易。
C/C++有上限值,也:
Maximum number of parameters in function declaration
以上给出像127(C)数字和256的C++。所以对于Lisp to C编译器来说,这可能是限制。否则,Lisp代码不会使用C函数调用。
第一个这样的编译器KCL(京都Common Lisp的,后来这个实施演变成GCL/GNU通用Lisp和ECL /可嵌入的Common Lisp)具有LispWorks/Mac OS X上的一个64的CALL-ARGUMENTS-LIMIT
甲64位实施例如CALL-ARGUMENTS-LIMIT
的值为2047。
CALL-ARGUMENTS-LIMIT
应不小于50 Common 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]
不是特别有用,当然.....
这个例子并没有说服我。 APPLY被两个参数调用。用无穷参数调用这个+是不明确的。可能APPLY忙BEFORE +被无限参数调用。以@jwinandy为例,显示Clojure以8192个参数“挂起”,我怀疑这里会发生同样的情况...... – 2015-01-07 08:15:59
这取决于实施。 “我建议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
这就是规格说明的内容,但是您是否知道实际执行限制的任何实现? – Marcin 2012-04-02 10:10:22
@Marcin好吧,SBCL保证您在10^18区域内有一个CALL-ARGUMENTS-LIMIT,我期望传递更多的参数,那根本行不通。我没有任何其他的实现,但我确实记得使用APPLY而不是REDUCE时遇到问题的人阅读与“在数百个元素中”一样短的列表。 – Vatine 2012-04-02 10:14:43
@Vatine我刚刚意识到我的标题和问题描述相互矛盾的意思。因为我认为你正在回答“+”函数的数值限制,你是否介意函数可能具有_inputs_的限制?对困惑感到抱歉! – Soyuz 2012-04-02 10:17:00