在Lisp中,+函数实际上有多少输入?

时间:2012-04-02 09:40:33

标签: lisp common-lisp

我对Lisp比较陌生,我想知道“+”函数是否确实存在上限。

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

5 个答案:

答案 0 :(得分:11)

是的,有一个上限,但确切的上限是依赖于实现的。你保证能够通过至少50,但这一切都取决于。如果你需要对一个列表求和,你可能会更好地使用(reduce #'+ list),这应该会比任何其他方法提供更好的可伸缩性。

Common Lisp HyperSpec还有更多信息。

当涉及到值范围时,有两种不同的情况,浮点数和整数。浮动本身就受到它们的大小的限制,并且从单浮动到双浮动的实现会让我感到惊讶。对于整数和有理数,CL在fixnums和bignums之间无缝转换,因此限制是实现可用的可用地址空间的函数。我怀疑复杂的数字(复杂的整数和有理数 - >如果需要,请转到bignums;复杂的浮点数 - >信号超出范围,或返回Inf或NaN)也是如此。

答案 1 :(得分:8)

Common Lisp的定义方式使其可以在各种硬件和软件系统上高效实施。例如摩托罗拉68000/20/30/40,各种英特尔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到C编译器,这些可能是限制。否则,Lisp代码不会使用C函数调用。

第一个这样的编译器KCL(Kyoto Common Lisp,后来这个实现演变为GCL / GNU Common Lisp和ECL / Embeddable Common Lisp)的CALL-ARGUMENTS-LIMIT为64。

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

CALL-ARGUMENTS-LIMIT不应小于50。

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

答案 2 :(得分:2)

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]

当然不是特别有用.....

答案 3 :(得分:2)

这取决于实施。 “我建议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

答案 4 :(得分:-1)

简单的回答,不,虽然使用递归而不是尾递归的不良实现会有堆栈限制。

取决于您的实现+可以使用递归或直接函数调用来实现。

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

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

编辑:由于某人实际上已经提供了一个Common Lisp引用,它显然应该是一个更好的答案,但我认为任何好的实现都会在提供足够的参数时自动应用等效的(reduce #'+ arg-list)