Şartlar için “ve” - “ne zaman”


13

Bu, bu cevabın yorumlarının bir devamıdır . Aşağıdaki kod parçaları eşdeğer gibi görünüyor:

(and a b)

(when a b)

Tabii anddaha koşullar koymak sağlar: (and a b c d)araçları(when (and a b c) d)

Ben whensadece dallanmayı ifade etme eğilimindeyim . Gerçek farklılıklar var mı? Birini veya diğerini kullanmak daha mı iyi?

Emacs'ın C kaynağı elimde değil; andbir C fonksiyonudur; when, genişleyen bir makrodur if, kendisi de C işlevidir.


"Elbette ve sağlar" olmalıdır "Elbette" ve "sağlar", ancak bu sadece 2 karakterlik bir değişikliktir ve izin verilen bir düzenleme değildir. Geçersiz kılma yok.
— Harvey

Yanıtlar:


18

TL; DR: when yan etkilerle ilgilidir, andsaf boole ifadeleri içindir.

Fark ettiğiniz gibi andve whensadece sözdiziminde farklılık gösterir, ancak aksi takdirde tamamen eşdeğerdir.

Sözdizimsel fark oldukça önemlidir, ancak: ilk argüman formları whendışındaki prognherkese örtülü olarak sarılır . progndoğası gereği zorunlu bir özelliktir: En son vücut formu dışındaki her şeyi sadece yan etkileri açısından değerlendirir ve geri döndürdükleri değeri atar.

Bu nedenle, whenzorunlu bir formdur: Ana amacı, yan etkili formları sarmaktır, çünkü sadece son formun değeri vücut için gerçekten önemlidir.

andÖte yandan, asıl amacı verilen argüman formlarının dönüş değerlerine bakmak olan saf bir işlevdir: Bağımsız değişkenlerinden prognherhangi birini açıkça sarmadıkça , her argüman formunun değeri önemlidir ve hiçbir değer göz ardı edilmez. .

Bu nedenle andve whenstilistik arasındaki gerçek fark : andSaf boole ifadeleri için ve whenyan etkili formların etrafına bir koruma koymak için kullanılır.

Bu nedenle, bunlar kötü stil:

;; `when' used for a pure boolean expression
(let ((use-buffer (when (buffer-live-p buffer)
                    (file-exists-p (buffer-file-name buffer)))))
  ...)

;; `and' used as guard around a side-effecting form
(and (buffer-file-name buffer) (write-region nil nil (buffer-file-name buffer)))

Ve bunlar iyi:

(let ((use-buffer (and (buffer-live-p buffer)
                       (file-exists-p (buffer-file-name buffer)))))
  ...)

(when (buffer-file-name buffer)
 (write-region nil nil (buffer-file-name buffer)))

Bazı insanların buna katılmadıklarını ve andyan etkileri korumak için mutlu bir şekilde kullandıklarını biliyorum , ancak bunun gerçekten kötü bir stil olduğunu düşünüyorum. Bir nedenden ötürü şu farklı formlara sahibiz: Sözdizimi önemlidir . Olmasaydı, hepimiz kullanacağız if, ki bu Emacs Lisp'de semantik olarak gerçekten ihtiyacınız olan tek koşullu form. Diğer tüm boolean ve koşullu formlar açısından yazılabilir if.


2
IMO (yani, stil ı kullanımda), andyaklaşık dönüş değeri hakkında bakmakta . Yan etkileri kullanmakla ilgili değildir. Programım dönüş değerini önemsiyorsa o zaman kullanıyorum and. Eğer değilse o zaman kullanırım when. IOW, when sadece yan etkiler için kullanıyorum , ancak prognargümanlardan birinde bir de kullanabilirim and. Dönüş değerinin önemli olup olmadığı, tek başına önemli olup olmadığı değil .
— Drew

5
andbildiğim Lisp'lerde bir işlev değil. Emacs Lisp'te bu özel bir form, Common Lisp'te bir makro, çünkü kısa devre davranışına sahip olması bekleniyor (işlevlerle başarılması imkansız, çünkü her zaman argümanlarını değerlendiriyorlar).
— Mark Karpov

2
@lunaryorn, Evet, gerçekten alakalı değil, ama bu doğru, bu yüzden andbir fonksiyonun, yanlış olduğunda yazmak yanlış olduğunu düşünüyorum . Sorunun gerçekle ne kadar alakalı olduğu önemli değil, her zaman doğru terimleri kullanmalıyız, hepsi bu.
— Mark Karpov

2
“Her argüman formunun değeri önemli” olduğunu düşünmüyorum, bu yorumun ne olduğu ile tutarlı. Hiçbir formun sadece değerinin atılması için değerlendirilmediğini söyleyerek daha iyi ifade edilebilirdi.
— Harald Hanche-Olsen

3
Biraz OT, ama: Fark Lisps'te, niltüm "yanlış", "boş liste", "geçersiz" vb . Anlamına gelmeyen, stilistik olmaktan daha fazlasıdır . Örneğin, Şema ve Racket'te whenolduğu void(yani, "bir anlamı") için ise ando #f( "sahte"). Bu Elisp için N / A olmasına rağmen, Lisp generalinin düşünebileceği bir şey.
— Greg Hendershott

4

Bunu söyleyerek başlayayım (and a b)ve (when a b)örneğinizde aynı şeyi yapın: Birincisi adeğerlendirilir. beğer değerlendirilir aolduğunu doğrudur # .

Ancak and ve whenfarklı şeyler için kullanılır.

  • Sen kullanırsınız (and a b)dönmek için gerçek # eğer İKİ ave bolan gerçek # (veya olmayan nil); ve nilbaşka türlü.

  • Kullanırsınız (when a b)veya daha doğru olursanız,

    (when a
       ;; do something like b
       )
    

    Eğer "B" kod yürütmek istediğinizde ancak ve ancak abir gerçek # .


Birlikte whenve andbirlikte kullandığınız bir örnek :

(when (and a b)
   (do-c))

Yukarıda, fonksiyon do-cSADECE İKİ eğer denir ave bvardır doğrudur # .


Çalışma için referanslar

# True ile ilgili tüm başvurular Boole TRUE değerine başvurur.


3
andttüm argümanları sıfır değilse döndürmez , ancak son argümanın değeri döndürmez .
— Anlamlı Kullanıcı Adı

1
By t, ben Boole TRUE veya olmayan nil anlamına geliyordu. Teşekkürler, cevabımda bunu açıklığa kavuşturacağım.
— Kaushal Modi

Cevabınızın soruda daha önce belirttiğimden çok daha ileri gittiğini düşünmüyorum; Her ikisinin de ne yaptığını biliyorum ve verdiğiniz son örnek zaten sorumda ( (when (and a b) c)) görünüyor. Buna ek olarak, genel olarak bu şekilde nasıl kullanıldıklarını andve whenönerdiklerini, ancak bu sorunun temelini, sık sık farklı kullandıklarını gördüm (örneğin soruma bağlandığım cevaba bakınız).
— Clément

Sadece fonksiyonel bir yapı noktası görüntüsü, kaynaktan olmayan sonlandırma değerlendirmeler için olup ve doğrudan sembol ve Boole mantık içindir. Fonksiyonel programlama bu ayrımı gerektirir; zorunlu programlama bunu ortadan kaldırıyor.
— Emacs Kullanıcısı

1
"Boolean true" nun "true" dan daha açık olduğunu düşünmüyorum.
— YoungFrog
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.