Soru Emacs # 'işlevi sözdizimi ne zaman kullanılmalıdır?


Temel olarak, Emacs Lisp’i ne zaman kullanmalıyım? function Prosedür? Fonksiyonları argüman olarak iletirseniz, davranışta bir farkın olduğu herhangi bir örnek bulamadım. 'like-this veya #'like-this. Aslında, değerlendirirsem (eq 'goto-char #'goto-char) döndürür t.

Karşılaştığım Emacs Lisp kodu nadiren kullanımları function/#'; sadece yazarlar quote/' herşey.
Örnek: (add-hook 'emacs-lisp-hook 'turn-on-eldoc-mode)

Ancak, birkaç counterexamples bulabilirim. İşte Emacs 24.3'ün kaynak kodlarından biri. electric.el:

(add-hook 'post-self-insert-hook
          #'electric-indent-post-self-insert-function
          'append)

Tahminler ve başka sorular:

  • Lisp-2 stilistik bir kongre mi?
  • Bayt derleme ile ilgisi var mı?
  • Sadece kitap yazarları için önemli mi? Kodunuzun çok sayıda ortam ve Emacs sürümünün altında çalıştırılmasını istiyorsanız? (Eğer sadece "dotfile-tinkering" iseniz, o zaman tüm bunlar için endişelenmenize gerek yoktur.
  • Ne zaman lambda ifadelerini kullanmalıyım? Onları ne zaman terkedemeyebilirim?
    Örneğin., (do-something '(lambda … 
    e karşı  (do-something (lambda …
  • Emacs'ın daha önceki bir versiyonunda elisp'in bu yönlerini ortaya çıkaran bir sınırlama var mıydı? Gibi, çoğunlukla arasındaki farkı göz ardı edebilir miyim ' ve #' Emacs'in bir sürümünü kullandığım sürece X?

26
2018-05-28 20:58


Menşei


Ayrıca bakınız stackoverflow.com/questions/18390586/... - Brian Burns
Okuyucular, faydalı okumalar yapmak için kenar çubuğunda "Bağlantılı" Q & As'ı bulabilirler. - phils


Cevaplar:


function (diğer adıyla #') işlevleri alıntılamak için kullanılır quote (diğer adıyla ') veri alıntılamak için kullanılır. Şimdi, Emacs-Lisp'de işlev hücresi bir işlev olan bir sembolün kendisi bir işlevdir. #'symbol sadece aynı 'symbol pratikte (niyet, farklıdır, ilk önce, sadece "sembol" sembolünden değil, "sembol" olarak adlandırılan işlevden) bahsetmektedir.

Farkın sadece üslup olmadığı yer lambdaların alıntılanması gereken yer: '(lambda ...) değerlendiren bir ifadedir liste ilk elemanı sembolü lambda. Gibi şeyler uygulamak için izin var car ve cdr ona göre, ama bir işlevmiş gibi çağırmamalısınız (pratikte gayet iyi çalışmasına rağmen). Aksine #'(lambda ...) (sadece yazılabilir (lambda ...)) değerlendiren bir ifadedir fonksiyon. Bu, uygulayamayacağın anlamına geliyor car ona, ama byte-derleyici içeride bakabilirsiniz #'(lambda ...), içinde makro-genişleme gerçekleştirmek, bulduğu şey koşucu, vb görünmüyorsa sizi uyarmak; Sözcüksel bağlama için bile zorunda Bu işlevin ifade ettiği serbest değişkenleri bulmak için içeriye bakın.


26
2018-05-28 22:09





Elisp'de #' (gerçekte) sadece byte derleme hakkındadüzenleme: ve Emacs 24'ten beri, sözcüksel kapanışlar); ama muhtemelen hiç kullanmanıza gerek yok.

#'... kısa el (function ...) sadece bir çeşidi olan '... / (quote ...) Ayrıca, byte-derleyicisine alıntılanan formu bir işlev olarak derleyebildiğini ima eder.

Ancak, modern Emaclarda (IIRC bu her zaman böyle değildi), (lambda ...) eşdeğerdir #'(lambda ...), bu yüzden nadiren inanıyorum (eğer) gerek yazmak #'.

Ayrıca nadiren kullanmak istersiniz '(lambda ...)Stefan'ın üzerinde durduğu sebeplerden dolayı (ama 'symbol iyi).

Bu kılavuzda ele alınmıştır Cı-sbeng  (elisp) Anonymous Functions  RET (Örnek kodun son parçasında, bir önceki örnekle aynı olduğu için (Emacs 24.3.1'de) bir hata gibi görünüyor).

(n.b. Stefan'ın cevabı kesin, fakat bunu umarım tamamlayıcı olarak kabul edeceğim.)


11
2018-05-28 22:09





Alıntıdaki farklılıklara ek olarak (lambda ...) Son zamanlarda meydana gelen formlar (Emacs 24.4'ten itibaren) bytecomp.el öyle ki bir uyarı üretildiğinde #'symbol form kullanılır, ancak işlev derlemenin sonunda tanımlandığı bilinmemektedir.

Tüm işlev sembollerini işlev alıntılama ile yazma #'symbol sözdizimi yerine 'symbol Bu nedenle sözdizimi biraz daha tercih edilir, çünkü gerçekte tanımlanmış işlev adlarını kullanıp kullanmadığınızı bayt-derleyicisinin denetlemesine izin verir.

Önceden (Emacs 24.3 ve önceki sürümler), byte-derleyici bir işlevi çağırdığınızda uyarır. (no-such-function ...) ve başka bir dosyadan tanımlanmamış veya temiz bir şekilde içe aktarılmadı (mapcar #'no-such-function ...) Bir derleme zamanı uyarısı olmadan yalnızca bir çalışma zamanı hatası üretecekti.

Değişim, bu senaryoların her ikisinin de şimdi derleme zamanı uyarıları üreteceği anlamına gelir; Ancak kullanırsanız (mapcar 'no-such-function ...)  olmadan işlev-alıntılama kullanılarak, bir kez daha, derleme zamanı uyarısı oluşturulamaz. Böylece #' hataları (muhtemelen yazım hataları) erken bulmanıza yardımcı olabilir.

İşlev-alıntılama, yukarıdan aşağıya bir programlama stili ile de yardımcı olur, çünkü byte-derleyici daha sonra henüz uygulamamış olduğunuz fonksiyonları listeleyecektir (ancak normal bir alıntıyla belirtilen işlevleri kaçıracaktır).


5
2017-09-24 13:18