Saya belajar lebih banyak tentang elisp dan menemui masalah berikut:
Jika saya ingin mengatur ulang variabel daftar, itu tidak akan diperbarui setelah evaluasi pertama. Berikut ini beberapa contoh kode:
(defun initilize ()
(setq example '(3)))
(defun modify ()
(initilize)
(message "%S" example)
(setcar example 2))
; M-x eval-buffer RET
(modify) ; message --> (3)
(modify) ; message --> (2)
(modify) ; message --> (2)
Saya tertarik pada dua hal. Yang pertama adalah untuk mempelajari lebih lanjut tentang apa yang terjadi "di bawah tenda" jadi mengapa itu bekerja pertama kali dan gagal pada panggilan berikutnya?
Pertanyaan kedua dan lebih praktis adalah bagaimana menginisialisasi ulang daftar dengan benar atau adakah cara lain yang umum untuk melakukan sesuatu seperti itu?
Satu solusi yang saya temukan sendiri adalah dengan menggunakan daftar yang dikutip dan mengevaluasi konten seperti ini:
(setq example `(,3))
example
belum pernah dinyatakan sebagai variabel, jadi setq
harus bertindak seolah-olah mendeklarasikan variabel baru, tetapi nanti ketika Anda memanggil initialize
lagi variabel baru sedang dibuat, sementara modify
mengingat yang lama ... dalam hal apa pun ini bukan perilaku yang diharapkan, namun, penggunaan setq
dengan sesuatu yang belum diperkenalkan sebelumnya sebagai variabel mungkin juga tidak terdefinisi.
'(3)
diperlakukan sebagai nilai literal, sehingga setelah Anda (setcar '(3) 2)
, setiap kali Anda melakukan (defvar foo '(3))
atau (let ((foo '(3)))
dan sebagainya Anda mungkin akan mendapatkan nilai foo
sama dengan '(2)
. Saya katakan "mungkin" karena perilaku ini tidak dijamin, itu semacam optimisasi yang dilakukan penerjemah kapan pun rasanya, sesuatu yang dikenal sebagai konstanta penghapusan subekspresi (kasus tertentu). Jadi, apa yang ditulis abo-abo sebenarnya bukan alasannya. Ini lebih seperti memodifikasi string literal dalam C (yang biasanya menghasilkan peringatan).
'(some list)
untuk menjadieq
ke'(some list)
- pernah .Ada umumnya ada jaminan dalam Lips bahwa kode yang tampak mengutip daftar kembali struktur daftar baru setiap kali. Dalam beberapa implementasi Lisp mungkin, atau mungkin beberapa waktu. Pada orang lain, itu tidak pernah terjadi. Kode Anda seharusnya tidak tergantung pada perilaku seperti itu dari implementasi. Jika Anda ingin struktur baru daftar, penggunaanlist
ataucons
atau setara.