简体   繁体   中英

In Lisp, how many inputs can the + function actually have?

I'm relatively new to Lisp, and I was wondering if there really is an upper limit to the "+" function.

(I guess this applies to all the other arithmetic functions "-", "/" etc.)

Yes, there is an upper limit, but the exact upper limit is implementation-dependent. You're guaranteed to be able to pass at least 50, but it all depends. If you need to sum a list, you're probably better off with (reduce #'+ list) , that should give you a much better scalability than any other method.

Common Lisp HyperSpec has some more info.

When it comes to value ranges there are two distinct cases, floats and integers. Floats are inherently limited by their size and an implementation that changed from single-floats to double-floats would surprise me a lot. With integers and rationals, CL seamlessly transition between fixnums and bignums, so the limit is a function of the usable address space available to the implementation. I suspect the same holds for complex numbers (complex integers and rationals -> go to bignums if needed; complex floats -> signal an out of range, or return an Inf or NaN).

Common Lisp has been defined in such a way that it could be implemented efficiently on a wide variety of hardware and software systems. Examples are processors like the Motorola 68000/20/30/40, the various Intel x86 processors, Lisp Machine stack-based processors, DEC VAX, RISC processors, super computers like those from Cray. In the 80s there were a lot of processor families competing, including processors developed for execution of Lisp code. Today we still have several processor families (x86, x86-64, ARM, SPARC, POWER, PowerPC, ...).

It can also be compiled to C, Scheme or other programming languages.

It can also be compiled to virtual machines like those of CMUCL, CLISP or the JVM / Java Virtual Machine (The Java Virtual Machine seems to have a limit of 254 arguments).

For example a Common Lisp compiler might compile Lisp code to straight-forward C code. Thus it would be good if as much of the function calling of the C compiler could be reused as possible. Especially also to make calling Lisp from C easier.

C/C++ has limits on that, too:

Maximum number of parameters in function declaration

Above gives numbers like 127 (C) and 256 for C++. So for a Lisp to C compiler these might be the limits. Otherwise the Lisp code would not use the C function calling.

The first such compiler KCL (Kyoto Common Lisp, later this implementation evolved into GCL / GNU Common Lisp and ECL / Embeddable Common Lisp) had a CALL-ARGUMENTS-LIMIT of 64.

A 64bit implementation of LispWorks / Mac OS X for example has a value of 2047 for CALL-ARGUMENTS-LIMIT .

CALL-ARGUMENTS-LIMIT should be no smaller than 50.

Thus in Common Lisp, list processing and calling arguments are not related. If you want to process lists, you have to use the list processing tools (LIST, MAPCAR, APPEND, REDUCE, ...). Common Lisp provides a mechanism to access the arguments as a list using a &REST parameter. But that should usually be avoided, since it might cause function calling overhead because a list of the arguments need to consed.

It depends of the implementation. "I would suggest LISP users take 5 minutes to test their platform".

For 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)

It doesn't terminate, it hangs at 8192 given my settings.

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

Clojure provides an example of a Lisp where you can actually have an infinite number of arguments to a function, via the use of lazy sequences:

; 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]

Not particularly useful, of course.....

Simple answer, no, although a poor implementation using recursion and not tail recursion will have a stack limit.

Depending upon your implementation + may be implemented using recursion or as a straight function call.

I don't know Common Lisp well enough to know what requirements it specifies, but most implementations, if they use recursion, will use tail recursion and avoid any stack limits.

A function call will be able to access the arguments as a list and so there is no limit to the number of arguments that can be processed.

EDIT: Since someone has actually given a Common Lisp reference, it clearly should be a better answer, but I would have thought any good implementation would automatically apply the equivalent of (reduce #'+ arg-list) when enough arguments are supplied.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM