Apa gunanya kutipan dengan argumen dan koma tunggal? (kutipan, arg)

15

(quote x)membuat x tidak dievaluasi, tetapi menambahkan ,di depan xdi quotedalamnya membuatnya dievaluasi. Apa itu titik menggunakan kutipan dengan satu argumen dengan koma di depannya, seperti: (quote ,x)?

Dimotivasi oleh garis 59 dari panah yang menjengkelkan :

(put (quote ,cmd) 'aa--alts ,alternatives)

Mengapa tidak (put cmd 'aa-alts ,alternatives)sama baiknya?

Kucing Unfun
sumber

Jawaban:

20

Koma digunakan dalam konteks daftar backquoted (alias quasiquoted), yang memungkinkan Anda untuk mengevaluasi beberapa bagian dari daftar secara selektif. Lihat juga utas ini untuk contoh penggunaan untuk backquoting.

Beberapa contoh sederhana:

(setq a "a's value" b "b's value" c "c's value")
'(a  b  c)                              ; => (a b c)
`(,a b ,c)                              ; => ("a's value" b "c's value")

Koma yang Anda maksudkan berada dalam definisi makro yang, pada gilirannya, menggunakan kutipan balik progn:

(defmacro add-annoying-arrows-advice (cmd alternatives)
  `(progn
     (add-to-list 'annoying-commands (quote ,cmd))
     (put (quote ,cmd) 'aa--alts ,alternatives)
     (defadvice ,cmd (before annoying-arrows activate)
       (when annoying-arrows-mode
         (aa--maybe-complain (quote ,cmd))))))

,cmddalam tanda kutip belakang memungkinkan Anda untuk menempatkan nilai cmddi tempat daripada simbol cmd.

Dan
sumber
1
Ackey, jadi kutipan di depan prognberarti Anda harus meletakkan koma di depan hal-hal yang ingin Anda evaluasi, tidak peduli seberapa jauh bersarang? (Ada di ,cmddalam daftar lain, bukan di dalam (progn).)
The Unfun Cat
Ini sepertinya kesempatan bagus untuk mengujinya! Coba evaluasi (setq a "a's value" b "b's value" c "c's value")dan evaluasi `(a '(,b c)).
Dan
Newb lain: untuk mengevaluasi menambahkan teks ke buffer awal Anda, kemudian tempatkan kursor Anda di akhir baris, lalu tekan Cxe.
The Unfun Cat
11

Itu karena itu di dalam makro. Makro harus mengembalikan formulir Lisp, yang kemudian dievaluasi.

Misalnya, melihat permohonan pertama makro ini:

(add-annoying-arrows-advice previous-line '(ace-jump-mode backward-paragraph isearch-backward ido-imenu smart-up))

Kami membutuhkan ekspansi untuk memuat:

(put 'previous-line 'aa-alts '(ace-jump-mode backward-paragraph isearch-backward ido-imenu smart-up))

itulah yang (quote ,cmd)mencapai. Jika makro akan menggunakan dataran cmdsebagai gantinya, itu akan disimpan secara harfiah dan ekspansi akan:

(put cmd 'aa-alts '(ace-jump-mode backward-paragraph isearch-backward ido-imenu smart-up))

yang merupakan kesalahan, karena cmdtidak didefinisikan di lingkungan tempat makro dipanggil.

legoscia
sumber
Ini juga penjelasan yang bagus. Terima kasih telah mengejanya.
The Unfun Cat