2012-04-02 20 views

回答

11

是的,有一個上限,但確切的上限取決於實現。你保證能夠通過至少50次,但這一切都取決於。如果你需要總結一個列表,你最好用(reduce #'+ list),這應該會給你一個比任何其他方法更好的可伸縮性。

Common Lisp HyperSpec有更多信息。

當涉及到值範圍有兩個不同的情況下,浮動和整數。浮游物本身受其尺寸的限制,並且從單浮游物變爲雙浮游物的實施方式會讓我大吃一驚。使用整數和有理數,CL可以在fixnums和bignum之間無縫轉換,因此限制是可用於實現的可用地址空間的函數。我懷疑對於複數(複雜整數和有理因素 - >如果需要的話去bignum;複雜浮點數 - >超出範圍,或返回Inf或NaN)也是如此。

+0

這就是規格說明的內容,但是您是否知道實際執行限制的任何實現? – Marcin 2012-04-02 10:10:22

+2

@Marcin好吧,SBCL保證您在10^18區域內有一個CALL-ARGUMENTS-LIMIT,我期望傳遞更多的參數,那根本行不通。我沒有任何其他的實現,但我確實記得使用APPLY而不是REDUCE時遇到問題的人閱讀與「在數百個元素中」一樣短的列表。 – Vatine 2012-04-02 10:14:43

+1

@Vatine我剛剛意識到我的標題和問題描述相互矛盾的意思。因爲我認爲你正在回答「+」函數的數值限制,你是否介意函數可能具有_inputs_的限制?對困惑感到抱歉! – Soyuz 2012-04-02 10:17:00

-1

答案很簡單,沒有,雖然使用遞歸而不是尾遞歸一個貧窮的實施將有一個堆棧限制。

根據您的實現+可能會使用遞歸或直接函數調用來實現。

我不太瞭解Common Lisp,知道它指定了什麼要求,但是大多數實現(如果它們使用遞歸)將使用尾遞歸併避免任何棧限制。

函數調用將能夠作爲列表訪問參數,因此對可以處理的參數數量沒有限制。

編輯:因爲有人實際上給了一個Common Lisp引用,它顯然應該是一個更好的答案,但我會認爲當提供足夠的參數時,任何好的實現都會自動應用(reduce #'+ arg-list)的等效。

+0

常見的Lisp通常不是尾遞歸。我有一種感覺,我已經讀到,他們不允許進行尾部呼叫優化是有原因的(儘管我可能會想到這一點)。 – Marcin 2012-04-02 09:51:47

+1

此外,沒有理由爲什麼實現會使用遞歸,因爲'reduce'和'loop'的可用性。 – Marcin 2012-04-02 09:56:29

+2

@Marcin如果你調整你的優化變量(主要是「速度」高和「調試」低,但請參閱你的實現手冊的具體細節),他們被允許進行尾部調用優化,大部分都是。 – Vatine 2012-04-02 09:57:43

8

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作爲列表訪問參數的機制。但通常應該避免這樣做,因爲它可能會導致函數調用開銷,因爲參數列表需要一致。

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] 

不是特別有用,當然.....

+0

這個例子並沒有說服我。 APPLY被兩個參數調用。用無窮參數調用這個+是不明確的。可能APPLY忙BEFORE +被無限參數調用。以@jwinandy爲例,顯示Clojure以8192個參數「掛起」,我懷疑這裏會發生同樣的情況...... – 2015-01-07 08:15:59

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 
相關問題