Apa perbedaan antara push dan add-to-list?

28

Saya telah menemukan bahwa paket-paket berbeda dalam instruksi instalasi mereka menggunakan push atau add-to-list (Misalnya menambahkan direktori ke load-path) dan saya bertanya-tanya apa perbedaannya dan seperti apa use case untuk masing-masingnya.

pencuri bayangan
sumber
1
Saya berjuang untuk mengonversi kode menjadi menggunakan add-to-listkode cl-pushnew, dan saya menemukan posting blog ini cukup mencerahkan: yoo2080.wordpress.com/2013/09/11/…
dangom

Jawaban:

22

Apa yang disebutkan #zck adalah satu perbedaan. Tetapi jika itu adalah satu-satunya perbedaan maka Anda bisa bertanya tentang cl-pushnewdan add-to-list.

Perbedaan penting lainnya: add-to-listadalah fungsi, yang artinya mengevaluasi semua argumennya, khususnya yang pertama. pushadalah makro (sebagaimana adanya cl-pushnew) - ia tidak mengevaluasi argumen keduanya; alih-alih, ia menafsirkannya sebagai tempat umum.

Misalnya, jika argumen kedua adalah simbol maka itu dianggap sebagai variabel, dan nilai argumen pertama dikonsolidasikan ke nilai simbol itu sebagai variabel, dan variabel diatur ke kontra baru itu.

Seperti yang dikatakan oleh string doc add-to-list:

This is handy to add some elements to configuration variables,
but please do not abuse it in Elisp code, where you are usually
better off using `push' or `cl-pushnew'.
Drew
sumber
6
Juga menurut byte-compiler:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba
(push (5 6) my-list)masih memberi saya kesalahan - 5bukan fungsi. Bagaimana ini berbeda dari add-to-listperilaku?
markasoftware
@markasoftware: Apa yang Anda coba lakukan? Jika Anda ingin mendorong daftar (5 6)ke tempat (nilai variabel) my-listmaka Anda perlu membuat daftar (5 6). Salah satu cara untuk melakukannya adalah menggunakan '(5 6); yang lain adalah menggunakan (list 5 6). pushmengevaluasi argumennya.
Drew
@Drew Anda mengatakan sekarang bahwa itu mengevaluasi argumen, tetapi jawaban Anda secara harfiah menyatakan "itu tidak mengevaluasi argumen pertama", yang merupakan sumber kebingungan saya.
markasoftware
@markasoftware: Maaf; Saya salah ketik - saya menulis "argumen pertama" di mana saya seharusnya menulis "argumen kedua". Diperbaiki sekarang - terima kasih. Argumen kedua pushadalah tempat, seperti variabel. Arg pertama dievaluasi, dikontribusikan ke nilai variabel itu, dan variabel diatur ke kontra baru itu. add-to-listmengevaluasi arg pertamanya untuk menghasilkan variabel yang nilainya diperbarui. pushtidak mengevaluasi arg kedua, yang merupakan variabel untuk memperbarui. Urutan arg dibalik antara keduanya.
Drew
15

Dari dokumentasi Emacs , atau C-h f push:

Makro: push listname elemen

Makro ini membuat daftar baru yang mobilnya elemen dan yang CDR-nya adalah daftar yang ditentukan oleh listname, dan menyimpan daftar itu di listname.

Dari halaman yang sama, atau C-h f add-to-list:

Fungsi: elemen simbol tambahkan-ke-daftar & tambahkan opsional-fn

Fungsi ini menetapkan simbol variabel dengan memasukkan elemen ke nilai lama, jika elemen belum menjadi anggota dari nilai itu.

Jadi add-to-listhanya mendorong jika elemen belum ada di sana.

kawan
sumber
cl-pushnewberperilaku seperti add-to-list.
sam boosalis
15

Perbedaan lain:

pushmenambahkan elemen ke awal daftar .

add-to-listmemungkinkan Anda untuk menambahkan elemen ke awal atau akhir daftar .

(setq testasdf nil)

(push 'a testasdf)

testasdf
(a)

(add-to-list 'testasdf 'b)

testasdf
(b a)

;; add element to the end
(add-to-list 'testasdf "hello" t)

testasdf
(b a "hello")
undostres
sumber