Keskin alıntılar ne zaman kullanılmalıdır?


10

Diğer insanların eLisp kodunda keskin alıntılar görüyorum ve bunları kendim kullanıyorum, ancak ne zaman uygun olduklarını ve ne zaman uygun olduklarını tamamen bilmiyorum.

Keskin tırnak işaretleri kullanılmasının uygun olduğu ve bunun yerine sıradan tek tırnakların ne zaman kullanılması gerektiği konusunda herkes netleşebilir mi?


3
nb Bu soru için burada veya SO üzerinde birçok kopya var
phils


1
Ben bunun bir kopya olduğunu sanmıyorum: emacs.stackexchange.com/questions/3595#' lambda ile kullanmakla ilgilidir (cevap temelde "asla" değil), oysa #'sembollere uygulanan @ izkon'un sorusu geçerlidir .
Stefan

Yanıtlar:


12

#'Sadece için kısaltmadır functiongibi, 'için kısaltmadır quote.

Bayt derleyicisine veya yorumlayıcıya ya da bir insan okuyucusuna, argümanının bir işlev olması (işlev olarak kabul edilir) olduğunu belirtmek istediğiniz herhangi bir yerde kullanabilirsiniz.

Birçok bağlamda, örneğin, ( quoteveya ') kullanmak yerine basitçe alıntı yaparsanız #'(veya kullanırsanız) , bağımsız değişkenin nasıl ele alınacağını belirler function. Örneğin, bir sembolün yalnızca symbol-functionözelliği için kullanıldığı , yani bir işlev olarak kullanıldığı bir bağlamda, yalnızca sembolü iletebilirsiniz (örneğin, alıntı yaparak veya değeri sembol olan bir değişkeni ileterek).

Ancak bazen #'bu bağlamlarda kullanırsanız kod daha net olur . Emacs-Lisp'in kendisi, sembolün bu bağlamlarda bir işlev olarak kullanıldığını anlasa bile, bunu kodun bir insan okuyucusu için vurgulamak yardımcı olabilir.

Diğer bazı Lisps'lerde, basitçe alıntılanan (ile ') veya alıntı yapılmayan lambda formlarının muamelesi, function( #') kullanılarak alıntılandığında bir fonksiyon pozisyonundaki kullanımlarından farklı olabilir . Ancak Emacs Lisp. Emacs Lisp'de fonksiyon olarak değerlendirilmesini istediğiniz lambda formunu (ya 'da #'sadece liste olarak değil) alıntılamanıza gerek yoktur . Sadece bir liste olarak, araba vb.İle işlenmesini istiyorsanız lambda, alıntı yapın (ile ') - aşağıdaki örnek bunu göstermektedir.

Anonim İşlevlerden (elisp) :

- Özel Form: function function-object

Bu özel form FUNCTION-OBJECTdeğerlendirilmeden geri döner .

Bu, quote(* not Alıntı: :) benzer. Ancak, aksine quote, FUNCTION-OBJECTbir işlev olarak kullanılması amaçlanan Emacs değerlendiricisi ve bayt derleyicisine bir not olarak hizmet eder . FUNCTION-OBJECTGeçerli bir lambda ifadesi olduğunu varsayarsak , bunun iki etkisi vardır:

• Kod bayt-derlendiğinde, FUNCTION-OBJECTbir bayt-kod fonksiyon nesnesine derlenir (* not Bayt Derleme: :).

• Sözcük bağlaması etkinleştirildiğinde, FUNCTION-OBJECTbir kapağa dönüştürülür. * Not Kapanışları ::.

Okuma sözdizimi #', kullanımın kısa yoludur function. Aşağıdaki formların hepsi eşdeğerdir:

(lambda (x) (* x x))
(function (lambda (x) (* x x)))
#'(lambda (x) (* x x))

Aşağıdaki örnekte, bir change-propertyişlevi üçüncü bağımsız değişkeni olarak alan ve ardından anonim bir işlev ileterek double-property yararlanan bir işlevi tanımlarız change-property:

(defun change-property (symbol prop function)
   (let ((value (get symbol prop)))
     (put symbol prop (funcall function value))))

(defun double-property (symbol prop)
   (change-property symbol prop (lambda (x) (* 2 x))))

lambdaFormu alıntılamadığımızı unutmayın .

Yukarıdaki kodu derlerseniz, anonim işlev de derlenir. Diyelim ki, isimsiz işlevi bir liste halinde vererek yapılandıysanız bu gerçekleşmez:

(defun double-property (symbol prop)
   (change-property symbol prop '(lambda (x) (* 2 x))))

Bu durumda, anonim işlev derlenmiş kodda lambda ifadesi olarak tutulur. Bayt-derleyici, bir liste gibi görünse de bu listenin bir işlev olduğunu varsayamaz, çünkü listeyi işlev change-propertyolarak kullanmayı amaçladığını bilmez .


9

#'(aka function) önünde kullanılabilir (lambda ...)ancak burada gereksizdir, bu yüzden gerçekten anlamlı olduğu tek yer olduğu gibi bir sembolün önündedir #'car. ELisp'de #'carve 'carneredeyse tamamen eşdeğerdir, bu nedenle temel amaçlardan biri sadece niyeti belgelemektir (yani, bu sembolü fonksiyon olarak kullanmayı planladığınız bu kodu kimin okuduğunu belirtmektir). Yine de, farkın daha önemli olduğu birkaç durum vardır:

  • Bayt derleyici bu belgelenmiş niyetten yararlanır ve yazdığınızda bir işlev olarak var #'carolup olmadığını kontrol eder carve bulamazsa, bu işleve bir çağrınız olduğu gibi bir uyarı verir. .
  • İçeride cl-fletve cl-labelsyalnızca #'fyerel olarak tanımlanmış işleve başvurabilir f, çünkü 'fyine de genel simgeye f(ve symbol-functionyuvasında hangi işlev depolanabilir ) atıfta bulunacaktır . Örneğin

    (cl-flet ((car (x y) (+ x y)))
      (list #'car 'car))
    =>
    ((closure nil (x y) (+ x y)) car)
    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.