Saya punya di bawah ini:
(setq some-variable "less")
Saya bingung mengapa saya harus menggunakan kutipan tunggal dengan boundp
tetapi tidak dengan bound-and-true-p
.
Contoh 1:
(when (boundp 'some-variable)
(message "some-variable is %s" some-variable))
Hasil:
"beberapa variabel kurang"
Contoh 2a:
(when (bound-and-true-p some-variable) ;; Note that using single-quote causes error
(message "some-variable is %s" some-variable))
Hasil:
"beberapa variabel kurang"
Contoh 2b:
(when (bound-and-true-p 'some-variable) ;; Note that using single-quote causes error
(message "some-variable is %s" some-variable))
Hasil:
dan: Argumen tipe yang salah: symbolp, (kutipan beberapa variabel)
setq
merupakan singkatanset quoted
, dan awalnya adalah makro yang diperluas ke(set 'some-variable "less")
. Secara umum, Elisp tidak terlalu konsisten tentang argumen yang dikutip vs yang tidak dikutip, tetapi fungsi apa pun (bukan makro) yang perlu berinteraksi dengan variabel alih-alih nilai akan mengambil argumennya yang dikutip (setq
menjadi pengecualian utama).bound-and-true-p
adalah makro yang bodoh. Atau lebih tepatnya, namanya bodoh. 99,99% dari waktu ketika Anda ingin melakukan(and (boundp 'FOO) FOO)
Anda melakukannya untuk menggunakan nilaiFOO
. Anda tidak melakukannya hanya untuk mendapatkan nilai kebenaran. (1) Makro tidak diperlukan - kode yang diganti sepele dan kecil. (2) Nama itu menyesatkan - ini tentang nilai variabel, bukan hanya menguji apakah nilai variabelnya atau tidaknil
.Jawaban:
Jawaban singkat
Jika Anda mencoba menggunakan variabel itu sendiri, maka gunakan
'some-variable
. Jika Anda mencoba menggunakan nilai yang disimpan dalam variabel, gunakansome-variable
.Penjelasan
Untuk definisi manual, silakan lihat manual .
'
dan(quote ...)
keduanya melakukan tujuan yang sama di emacs-lisp.Tujuan dari ini adalah untuk menyerahkan formulir yang tidak dievaluasi ke lingkungan sekitarnya daripada mengevaluasinya.
Dalam contoh Anda anggap kita memiliki yang lebih tinggi berikut
Kemudian evaluasi berjalan sebagai berikut:
Sedangkan tanpa kutipan:
Lisp mengevaluasi formulir ketika sudah tercapai, dengan mengutip formulir yang Anda hindari evaluasi sehingga variabel aktual (atau daftar, atau nama fungsi) dilewatkan.
sumber
bound-and-truep
dan pertanyaannya adalah mengapa saya harus mengutip ketika menggunakanboundp
tetapi tidak saat menggunakanbound-and-truep
.boundp
membutuhkan simbol (tidak dievaluasi) danbound-and-truep
membutuhkan nilai variabel dalam poin-poin (diedit setelah jawaban awal)Simbol yang berada di posisi non-fungsi diperlakukan sebagai nama variabel. In
(function variable)
function
adalah dalam fungsi-posisi (setelah tanda kurung buka) danvariable
tidak. Kecuali jika variabel yang dikutip secara eksplisit diganti dengan nilainya.Jika Anda menulis
(boundp my-variable)
itu berarti "adalah simbol yang disimpan dalam nilai variabelmy-variable
terikat sebagai variabel" dan bukan "adalah simbol yangmy-variable
terikat sebagai variabel.Jadi mengapa
bound-and-truep
berperilaku berbeda?Ini adalah makro dan aturan evaluasi normal (fungsi) tidak berlaku di sini, makro bebas untuk memutuskan apakah dan kapan argumen mereka dievaluasi. Apa yang sebenarnya dilakukan makro adalah entah bagaimana mengubah argumen dan mengembalikan hasilnya sebagai daftar, yang kemudian dievaluasi. Transformasi dan evaluasi akhir terjadi pada waktu yang berbeda, yang disebut waktu ekspansi-makro dan waktu evaluasi.
Seperti inilah definisi
bound-and-true-p
tampilannya:Ini menggunakan macro pembaca yang berbeda dari macro lisp (lebih lanjut tentang itu di bawah). Untuk tidak mempersulit hal ini lebih lanjut, jangan gunakan makro pembaca apa pun:
Jika kamu menulis
yang pertama "diterjemahkan" ke
dan kemudian itu dievaluasi kembali
nil
jikamy-variable
tidakboundp
atau nilaimy-variable
(yang tentu saja bisa juganil
).Anda mungkin memperhatikan bahwa ekspansi tidak
seperti yang bisa kita harapkan.
quote
adalah bentuk khusus, bukan makro atau fungsi. Seperti makro, bentuk khusus dapat melakukan apa pun dengan argumen mereka. Bentuk khusus khusus ini hanya mengembalikan argumennya, di sini simbol, bukan nilai variabel simbol. Itu sebenarnya satu-satunya tujuan bentuk khusus ini: mencegah evaluasi! Macro tidak dapat melakukannya sendiri, mereka perlu menggunakannyaquote
untuk melakukannya.Jadi ada apa
'
? Ini adalah makro pembaca , yang seperti disebutkan di atas tidak sama dengan makro pelat . Sementara makro digunakan untuk mengubah kode / data, makro pembaca digunakan sebelumnya ketika membaca teks untuk mengubah teks menjadi kode / data.adalah bentuk singkat untuk
`
definisi sebenarnya yang digunakanbound-and-true-p
juga adalah pembaca makro. Jika mengutip simbol seperti di`symbol
dalamnya setara dengan'symbol
, tetapi ketika digunakan untuk mengutip daftar seperti di`(foo bar ,baz)
dalamnya berperilaku berbeda dalam bentuk yang diawali dengan,
dievaluasi.setara dengan
Ini harus menjawab pertanyaan mengapa simbol-simbol yang tidak dikutip kadang-kadang dievaluasi (diganti dengan nilainya) dan terkadang tidak; makro dapat digunakan
quote
untuk mencegah simbol dievaluasi.Tapi mengapa
bound-and-true-p
makro sementaraboundp
tidak? Kita harus dapat menentukan apakah simbol sewenang-wenang, yang tidak dikenal sampai waktu berjalan, terikat sebagai simbol. Ini tidak akan mungkin terjadi jikaboundp
argumen dikutip secara otomatis.bound-and-true-p
digunakan untuk menentukan apakah variabel yang dikenal didefinisikan dan jika demikian gunakan nilainya. Ini berguna jika perpustakaan memiliki ketergantungan opsional pada perpustakaan pihak ketiga seperti pada:bound-and-true-p
dapat didefinisikan sebagai fungsi dan memerlukan argumen untuk dikutip tetapi karena itu dimaksudkan untuk kasus-kasus di mana Anda tahu di muka variabel apa yang Anda pedulikan tentang makro yang digunakan untuk menyelamatkan Anda dari keharusan mengetik'
.sumber
Dari kode sumber
boundp
:boundp
mengharapkan asymbol
sebagai input.'some-variable
adalah simbol untuk variabelsome-variable
.Dari kode sumber
bound-and-true-p
:bound-and-true-p
mengharapkan avariable
sebagai input.Di dalam
bound-and-true-p
makro, ia mendapat simbol dengan melakukan(quote ,var)
. Jadi jika inputnya adalahsome-variable
,(quote ,var)
akan menghasilkan'some-variable
.Tapi ketika saya memberikan masukan
'some-variable
untukbound-and-true-p
, saya mendapatkan error:and: Wrong type argument: symbolp, (quote some-variable)
karena makro TIDAK mengharapkan simbol ('some-variable
) pada masukan.sumber
''symbol
memang masuk akal. Artinya(quote (quote symbol))
. Alasan Anda mendapatkan kesalahan adalah karena itu bukan argumen yang validboundp
.