Pertanyaan Di Lisp, berapa banyak input yang bisa dimiliki oleh fungsi +?


Saya relatif baru untuk Lisp, dan saya bertanya-tanya apakah memang ada batas atas untuk fungsi "+".

(Saya kira ini berlaku untuk semua fungsi aritmatika lainnya "-", "/" dll.)


7
2018-04-02 09:40


asal


Jawaban:


Ya, ada batas atas, tetapi batas atas yang pasti tergantung pada implementasi. Anda dijamin dapat lulus setidaknya 50, tetapi semuanya tergantung. Jika Anda perlu menjumlahkan daftar, Anda mungkin lebih baik dengan (reduce #'+ list), yang seharusnya memberi Anda skalabilitas yang jauh lebih baik daripada metode lainnya.

Common Lisp HyperSpec memiliki beberapa info lebih lanjut.

Ketika datang ke rentang nilai ada dua kasus berbeda, pelampung dan bilangan bulat. Floats secara inheren dibatasi oleh ukurannya dan implementasi yang berubah dari single-float ke double-floats akan mengejutkan saya banyak. Dengan bilangan bulat dan rationals, CL transisi mulus antara fixnum dan bignums, sehingga batas adalah fungsi dari ruang alamat yang dapat digunakan yang tersedia untuk implementasi. Saya menduga hal yang sama berlaku untuk bilangan kompleks (bilangan bulat kompleks dan rationals -> pergi ke bignums jika diperlukan; float kompleks -> sinyal di luar jangkauan, atau mengembalikan Inf atau NaN).


11
2018-04-02 09:55



Common Lisp telah didefinisikan sedemikian rupa sehingga dapat diterapkan secara efisien pada berbagai macam perangkat keras dan sistem perangkat lunak. Contohnya adalah prosesor seperti Motorola 68000/20/30/40, berbagai prosesor Intel x86, prosesor berbasis tumpukan Lisp Machine, DEC VAX, prosesor RISC, komputer super seperti yang berasal dari Cray. Pada tahun 80-an ada banyak keluarga prosesor yang bersaing, termasuk prosesor yang dikembangkan untuk eksekusi kode Lisp. Hari ini kita masih memiliki beberapa keluarga prosesor (x86, x86-64, ARM, SPARC, POWER, PowerPC, ...).

Ini juga dapat dikompilasi ke C, Skema atau bahasa pemrograman lainnya.

Ini juga dapat dikompilasi ke mesin virtual seperti CMUCL, CLISP atau JVM / Java Virtual Machine (Java Virtual Machine tampaknya memiliki batasan 254 argumen).

Sebagai contoh kompilator Common Lisp mungkin mengkompilasi kode Lisp ke kode C langsung ke depan. Jadi akan lebih baik jika banyak fungsi memanggil kompiler C dapat digunakan kembali sebaik mungkin. Terutama juga untuk membuat panggilan Lisp dari C lebih mudah.

C / C ++ memiliki batasan untuk itu juga:

Jumlah parameter maksimum dalam deklarasi fungsi

Di atas memberikan angka seperti 127 (C) dan 256 untuk C ++. Jadi untuk Lisp ke C compiler, ini mungkin batasnya. Kalau tidak, kode Lisp tidak akan menggunakan pemanggilan fungsi C.

Kompiler pertama seperti KCL (Kyoto Common Lisp, kemudian implementasi ini berevolusi menjadi GCL / GNU Common Lisp dan ECL / Embeddable Common Lisp) memiliki CALL-ARGUMENTS-LIMIT dari 64.

Implementasi 64bit LispWorks / Mac OS X misalnya memiliki nilai 2047 untuk CALL-ARGUMENTS-LIMIT.

CALL-ARGUMENTS-LIMIT seharusnya tidak lebih kecil dari 50.

Jadi dalam Common Lisp, pemrosesan daftar dan argumen panggilan tidak terkait. Jika Anda ingin memproses daftar, Anda harus menggunakan alat pemrosesan daftar (DAFTAR, MAPCAR, BANYAK, REDUCE, ...). Common Lisp menyediakan mekanisme untuk mengakses argumen sebagai daftar menggunakan &RESTparameter. Tapi itu biasanya harus dihindari, karena mungkin menyebabkan fungsi memanggil overhead karena daftar argumen perlu dikonsolidasikan.


8
2018-04-02 13:25



Clojure memberikan contoh Lisp di mana Anda benar-benar dapat memiliki jumlah argumen tak terbatas ke fungsi, melalui penggunaan urutan malas:

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

Tidak terlalu berguna, tentu saja .....


2
2018-04-03 10:53



Itu tergantung implementasi. "Saya akan menyarankan pengguna LISP mengambil 5 menit untuk menguji platform mereka".

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

Itu tidak berakhir, itu tergantung pada 8192 diberikan pengaturan saya.

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

2
2018-01-07 04:10



Jawaban sederhana, tidak, meskipun implementasi yang buruk menggunakan rekursi dan bukan rekursi ekor akan memiliki batas stack.

Tergantung pada implementasi Anda + dapat diimplementasikan menggunakan rekursi atau sebagai panggilan fungsi lurus.

Saya tidak tahu Common Lisp cukup baik untuk mengetahui persyaratan apa yang ditentukan, tetapi sebagian besar implementasi, jika mereka menggunakan rekursi, akan menggunakan rekursi ekor dan menghindari batas tumpukan.

Panggilan fungsi akan dapat mengakses argumen sebagai daftar sehingga tidak ada batasan untuk jumlah argumen yang dapat diproses.

EDIT: Karena seseorang telah benar-benar memberikan referensi Common Lisp, itu jelas harus menjadi jawaban yang lebih baik, tapi saya akan berpikir implementasi yang baik akan secara otomatis menerapkan setara dengan (reduce #'+ arg-list) ketika cukup banyak argumen diberikan.


-1
2018-04-02 09:50