İşlevsiz pozisyonda olan bir sembol değişken değişken adı olarak kabul edilir. In (function variable)
function
fonksiyonu pozisyonunda (parantezin açılmasından sonra) ve variable
değ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-variable
sı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-truep
farklı 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-p
Gö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 nil
halinde my-variable
değil boundp
değ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-p
bir okuyucu makrosu. Bir sembolün içinde `symbol
olduğ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; quote
Bir sembolün değerlendirilmesini önlemek için makrolar kullanılabilir .
Fakat neden bound-and-true-p
bir makro boundp
olmasın? Çalışma zamanına kadar bilinmeyen rastgele sembollerin sembol olarak bağlanıp bağlanmadığını belirleyebilmeliyiz. boundp
Argüman otomatik olarak alıntılandıysa, bu mümkün olmazdı .
bound-and-true-p
Bilinen 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-p
bir 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 '
.
setq
anlamına geldiğiniset quoted
ve 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 (setq
büyük bir istisna olmak).