Jest to kontynuacja komentarzy do tej odpowiedzi . Następujące fragmenty kodu wydają się równoważne:
(and a b)
(when a b)
Oczywiście and
pozwala stawiać więcej warunków: (and a b c d)
oznacza(when (and a b c) d)
Zwykle używam when
tylko do wyrażania rozgałęzień. Czy istnieją rzeczywiste różnice? Czy lepiej jest używać jednego lub drugiego?
Nie mam pod ręką źródła Emacsa C; and
jest funkcją C; when
to makro, które rozwija się do siebie if
, co samo w sobie jest funkcją C.
elisp
elisp-macros
conditionals
Łaskawy
źródło
źródło
Odpowiedzi:
TL; DR:
when
dotyczy efektów ubocznych,and
służy wyłącznie do wyrażeń boolowskich.Jak zauważyłeś
and
iwhen
różnią się tylko składnią, ale poza tym są całkowicie równoważne.Różnica składniowa jest jednak dość ważna:
when
obejmuje niejawne podejścieprogn
wokół wszystkich form argumentów oprócz pierwszego.progn
jest z natury imperatywną cechą: ocenia wszystkie formy ciała oprócz ostatniej pod kątem ich skutków ubocznych, odrzucając jakąkolwiek wartość, którą zwrócili.Jako taka
when
jest również formą imperatywną: jej głównym celem jest owijanie form wywołujących skutki uboczne, ponieważ tylko wartość ostatniej formy ma znaczenie dla ciała.and
z drugiej strony jest funkcją czystą, której głównym celem jest przyjrzenie się wartościom zwrotnym podanych form argumentów: chyba że jawnie obejdzieszprogn
którykolwiek z jego argumentów, wartość każdej formy argumentu jest ważna i żadna wartość nigdy nie jest ignorowana .Stąd prawdziwa różnica między stylistyczną
and
iwhen
stylistyczną: używaszand
do wyrażeń czysto boolowskich iwhen
strzeżesz form ubocznych.Dlatego są to zły styl:
A te są dobre:
Wiem, że niektórzy nie zgadzają się z tym i chętnie używają
and
do ochrony przed efektami ubocznymi, ale myślę, że to naprawdę zły styl. Mamy różne formy z jednego powodu: Składnia ma znaczenie . Gdyby tak nie było, wszyscy użylibyśmy tylkoif
tej jedynej warunkowej formy, której naprawdę potrzebujesz semantycznie w Emacs Lisp. Wszystkie inne formy logiczne i warunkowe można zapisać w kategoriachif
.źródło
and
dotyczy dbania o wartość zwracaną . Niekoniecznie chodzi o stosowanie efektów ubocznych. Jeśli mój program dba o wartość zwracaną, używamand
. Jeśli nie, to używamwhen
. IOW, używamwhen
tylko do efektów ubocznych, ale równie dobrze mogę użyćprogn
jednego z argumentówand
. Chodzi o to, czy wartość zwrotu ma znaczenie, a nie o to, czy ma ona znaczenie sama .and
nie jest funkcją w żadnym znanym mi Lisp. W Emacs Lisp jest to specjalna forma, w Common Lisp jest to makro, po prostu dlatego, że oczekuje się zachowania zwarciowego (niemożliwe do osiągnięcia za pomocą funkcji, ponieważ zawsze oceniają swoje argumenty).and
jest funkcją, jeśli nie jest. Nie ma znaczenia, jak istotny jest fakt, że pytanie powinno być zawsze prawidłowe. To wszystko.nil
oznacza wszystkich „fałsz”, „pustej listy”, „pustki” itp. Na przykład w Scheme and Racket nieprawdziwy wynikwhen
jestvoid
(tzn. „bez znaczenia”), podczasand
gdy jest#f
(„fałsz”). Chociaż dla Elisp jest to nie dotyczy, jest to coś, co może rozważyć generalista Lisp.Zacznę od stwierdzenia, że
(and a b)
i(when a b)
na swoim przykładzie zrobić to samo: po pierwszea
jest oceniany.b
jest oceniane, jeślia
jest prawdą # .Ale
and
iwhen
są używane do różnych rzeczy.Użyłbyś
(and a b)
do zwrócenia true #, jeśli BOTHa
ib
są true # (lub non-zero); inil
inaczej.Użyłbyś
(when a b)
lub żeby być bardziej poprawnym,kiedy chcesz, aby kod „b” był wykonywany wtedy i tylko wtedy, gdy
a
jest to prawda # .Oto przykład, w którym używasz
when
iand
razem:Powyżej funkcja
do-c
jest wywoływana TYLKO, jeśli OBAa
ib
są prawdziwe # .Referencje do badań
when
sekcji tutaj)and
sekcji tutaj)# Wszystkie odniesienia do prawdy odnoszą się do logicznej wartości PRAWDA.
źródło
and
nie zwraca,t
jeśli wszystkie jego argumenty są inne niż zero, ale wartość ostatniego argumentu.t
miałem na myśli wartość logiczną PRAWDA lub brak wartości zero. Dzięki, wyjaśnię to w mojej odpowiedzi.(when (and a b) c)
). Ponadto część dotycząca tego, w jaki sposóband
iwhen
sugeruje, że tak naprawdę są one ogólnie używane, ale sama podstawa tego pytania polegała na tym, że często widzę, że są one używane inaczej (patrz na przykład odpowiedź, do której podałem pytanie).