Bagaimana cara defalias lambda?

8

Saya punya ini di .emacs saya:

(defalias 'λ 'lambda)

yang berfungsi dengan baik untuk hal-hal sederhana seperti (funcall (λ (x) x) 1).

Tetapi ketika saya melakukan sesuatu seperti (org-add-link-type "foo" (λ (s) (message s)))atau (add-to-list 'auto-mode-alist '("foo" . (λ () (message "bar")))), itu tidak berhasil dan saya mendapatkannya

org-open-at-point: Fungsi tidak valid: (λ (s) (pesan s))

dan

Kesalahan spesifikasi mode file: (fungsi tidak valid (λ nil (pesan "bilah")))

masing-masing.

Adakah yang tahu apa yang salah di sini?

rtrn
sumber
4
Bukan jawaban untuk pertanyaan tentang defalias, tetapi Anda mungkin ingin memeriksa prettify-symbols-mode, yang, antara lain, akan memungkinkan Anda untuk menampilkan lambdasebagai λtanpa benar-benar mengubah teks yang mendasarinya.
Dan
Sebuah perpustakaan sederhana yang prettifies hanya lambda (untuk λ): pretty-lambdada.el.
Drew
Jika Anda hanya ingin simbol yang cantik, gunakan github.com/akatov/pretty-mode
grettke

Jawaban:

11

Dengan bantuan dari lunaryorn pada reddit , saya kira saya telah dapat memahami mengapa Anda mengamati perilaku "aneh".

Masalahnya adalah Anda mengutip ungkapan tersebut

'("foo" . (λ () (message "bar")))

Yang setara dengan formulir

(cons "foo" '(λ () (message "bar")))

Sekarang ketika emacs membuka file dengan ekstensi "foo", ia melakukan sesuatu seperti berikut ini

(funcall '(λ () (message "bar")))

Perhatikan kutipan tambahan, sebelumnya , ini jelas bukan fungsi yang valid dan Anda mendapatkan kesalahan Invalid function: ... Tapi mengapa ("foo" . (lambda () (message "bar")))berhasil, ini dijelaskan oleh pengamatan lunaryorn

"Daftar lambda", yaitu daftar yang mobilnya lambda, adalah fungsi yang valid juga

Begitu '(lambda () (message "bar"))juga fungsi yang valid, ini bisa diverifikasi dengan kode berikut

(functionp (lambda () "hello"))  => t
(functionp (λ () "hello"))       => t
(functionp '(lambda () "hello")) => t
(functionp '(λ () "hello"))      => nil

Jadi solusinya adalah dengan tidak mengutip ekspresi gunakan yang berikut ini sebagai gantinya

(add-to-list 'auto-mode-alist (cons "foo" (λ () (bar))))
Iqbal Ansari
sumber
Terima kasih atas penjelasannya! Semuanya bekerja dengan baik sekarang :)
rtrn
3

Sepertinya masalahnya bukan pada defalias, melainkan di mana dan bagaimana Anda menelepon λ. funcallmengambil, sebagai argumennya, fungsi dan argumen fungsi itu, jadi funcallcontoh Anda berfungsi dengan baik.

Baik org-add-link-typedan auto-mode-alist, bagaimanapun, mengharapkan simbol yang berisi fungsi yang relevan. Karena itu, membangun contoh Anda, berikut ini harus bekerja:

(defun a-silly-fnx (s)
  (message s))
(defalias #'my-link-alias #'a-silly-fnx)
(org-add-link-type "foo" #'my-link-alias)

(defun a-tester-fnx ()
  (message "Testing!")
  (sit-for 2))
(defalias #'my-alist-alias #'a-tester-fnx)
(add-to-list 'auto-mode-alist '("foo" . my-alist-alias))

Jika Anda kebanyakan ingin memiliki λmuncul dalam buffer Anda, pertimbangkan mencoba prettify-symbols-mode, yang akan menampilkan lambdasebagai λtanpa mengubah teks th buffer.

Dan
sumber
Yang aneh adalah semuanya bekerja dengan baik ketika saya menggunakan lambdasecara langsung.
rtrn
@ trn: ah, poin bagus. Saya menduga itu karena lambdamakro mengembalikan lambdabentuk khusus yang dikutip sendiri yang alias tidak diambil, tetapi mungkin ada lebih banyak ilmu hitam di sini. Panggil @Malabarba.
Dan