İşlevsiz pozisyonda olan bir sembol değişken değişken adı olarak kabul edilir. In (function variable) functionfonksiyonu pozisyonunda (parantezin açılmasından sonra) ve variabledeğil. Açıkça belirtilmediği sürece değişkenler değerleri ile değiştirilir.
Eğer yazacak (boundp my-variable)olsaydınız, "değişken olarak my-variablesınırlanan değişken değerinde saklanan sembol" anlamına gelmez, " değişken değil olarak bağlanan sembol" anlamına gelir my-variable.
Peki neden bound-and-truepfarklı davranıyor?
Bu bir makrodur ve normal (işlev) değerlendirme kuralları burada uygulanmaz, makrolar argümanlarının değerlendirilip değerlendirilmediğine ve ne zaman değerlendirileceğine karar vermede serbesttir. Makroların gerçekte yaptığı şey, bir şekilde argümanları dönüştürmek ve sonucu, ardından değerlendirilen bir liste olarak döndürmektir. Dönüşüm ve nihai değerlendirme, makro genişleme zamanı ve değerlendirme zamanı olarak adlandırılan farklı zamanlarda gerçekleşir.
bound-and-true-pGörünüşün tanımı şöyle:
(defmacro bound-and-true-p (var)
"Return the value of symbol VAR if it is bound, else nil."
`(and (boundp (quote ,var)) ,var))
Bu, lisp makrolarından farklı olan okuyucu makrolarını kullanır (aşağıda daha fazlası). Bunu daha da karmaşıklaştırmamak, okuyucu makrolarını kullanmamakta:
(defmacro bound-and-true-p (var)
"Return the value of symbol VAR if it is bound, else nil."
(list 'and (list 'boundp (list 'quote var)) var))
Eğer yazarsan
(bound-and-true-p my-variable)
Bu ilk "tercüme" edilir
(and (boundp 'my-variable) my-variable)
ve daha sonra, geri dönüş değerlendirilir nilhalinde my-variabledeğil boundpdeğeri ya da başka bir my-variable(tabii ki, aynı zamanda olabilen nil).
Genişlemenin olmadığını fark etmiş olabilirsiniz.
(and (boundp (quote my-variable)) my-variable)
Beklediğimiz gibi. quoteözel bir formdur, makro veya işlev değildir. Makrolar gibi, özel formlar argümanlarıyla ne yapabilirlerse. Bu özel özel form, argümanını, burada sembolün değişken değeri yerine bir sembol olarak döndürür. Aslında bu özel formun tek amacı bu: Değerlendirmeyi engellemek! Makrolar bunu kendi başlarına yapamazlar quote, bunu yapmak için kullanmaları gerekir .
Peki neyin var '? Yukarıda da belirtildiği gibi bir lisp makrosu ile aynı olmayan bir okuyucu makrosudur . Makrolar kodu / verileri dönüştürmek için kullanılırken, metinleri okurken daha önce bu metni kod / verilere dönüştürmek için okuyucu makrolar kullanılır.
'something
kısaca
(quote something)
`Asıl tanımında kullanılan bound-and-true-pbir okuyucu makrosu. Bir sembolün içinde `symbololduğu gibi bir eşittir 'symbol, ancak bir listeyi alıntı yapmak için kullanıldığında `(foo bar ,baz), öneki olan formlarda farklı davranır ,.
`(constant ,variable)
eşittir
(list (quote constant) variable))
Bu, işaretsiz sembollerin neden bazen değerlendirildiğini (değerleriyle değiştirildiğini) bazen de sorulmadığı sorusuna cevap vermelidir; quoteBir sembolün değerlendirilmesini önlemek için makrolar kullanılabilir .
Fakat neden bound-and-true-pbir makro boundpolmasın? Çalışma zamanına kadar bilinmeyen rastgele sembollerin sembol olarak bağlanıp bağlanmadığını belirleyebilmeliyiz. boundpArgüman otomatik olarak alıntılandıysa, bu mümkün olmazdı .
bound-and-true-pBilinen bir değişkenin tanımlanıp tanımlanmadığını belirlemek için kullanılır ve öyleyse değerini kullanın. Bir kitaplığın, aşağıdaki gibi üçüncü taraf bir kitaplığa isteğe bağlı bir bağımlılığı varsa, kullanışlıdır :
(defun foo-get-value ()
(or (bound-and-true-p bar-value)
;; we have to calculate the value ourselves
(our own inefficient or otherwise undesirable variant)))
bound-and-true-pbir işlev olarak tanımlanabilir ve argümanın alıntılanmasını gerektirebilir, ancak bir makroya ne tür bir değer verdiğinizi önceden bildiğiniz durumlar için tasarlandığından, sizi yazmaktan kurtarmak için kullanılır '.
setqanlamına geldiğiniset quotedve aslında içine genişleyen bir makro olduğunu söylemeye değer(set 'some-variable "less"). Genel olarak, Elisp alıntı ve alıntı olmayan argümanlar hakkında oldukça tutarlı değildir, ancak bir değer yerine bir değişkenle etkileşime girmesi gereken herhangi bir fonksiyon (makro değil) alıntılanacaktır (setqbüyük bir istisna olmak).