Il s'agit d'un suivi des commentaires sur cette réponse . Les bits de code suivants semblent être équivalents:
(and a b)
(when a b)
Bien sûr, and
vous permet de mettre plus de conditions: (and a b c d)
signifie(when (and a b c) d)
J'ai tendance à utiliser when
uniquement pour exprimer la ramification. Existe-t-il des différences réelles? Vaut-il mieux utiliser l'un ou l'autre?
Je n'ai pas la source C d'Emacs à portée de main; and
est une fonction C; when
est une macro qui se développe en if
, qui est elle-même une fonction C.
elisp
elisp-macros
conditionals
Clément
la source
la source
Réponses:
TL; DR:
when
concerne les effets secondaires,and
concerne les expressions booléennes pures.Comme vous l'avez remarqué,
and
etwhen
ne diffèrent que par la syntaxe, mais sont par ailleurs entièrement équivalents.La différence syntaxique est assez importante, cependant:
when
enveloppe un impliciteprogn
autour de toutes les formes sauf les premiers arguments.progn
est une caractéristique intrinsèquement impérative: il évalue tous, sauf la toute dernière forme corporelle, pour leurs effets secondaires uniquement, en rejetant la valeur qu'ils ont renvoyée.En tant que tel, il
when
s'agit également d'une forme impérative: son objectif principal est d'envelopper les formes à effets secondaires, car seule la valeur de la toute dernière forme importe réellement pour le corps.and
d'autre part, est une fonction pure, dont le but principal est de regarder les valeurs de retour des formes d'argument données: à moins que vous neprogn
contourniez explicitement l' un de ses arguments, la valeur de chaque forme d'argument est importante et aucune valeur n'est jamais ignorée .Par conséquent, la vraie différence entre
and
etwhen
est stylistique: vous utilisezand
pour des expressions booléennes pures etwhen
pour mettre une garde autour des formes à effets secondaires.Par conséquent, ce sont de mauvais style:
Et ce sont bien:
Je sais que certaines personnes sont en désaccord à ce sujet et utilisent heureusement
and
pour protéger les effets secondaires, mais je pense que c'est vraiment un mauvais style. Nous avons ces différentes formes pour une raison: la syntaxe est importante . Si ce n'était pas le cas, nous n'utiliserions que jamaisif
, qui est la seule forme conditionnelle dont vous avez vraiment besoin dans Emacs Lisp sémantiquement. Toutes les autres formes booléennes et conditionnelles peuvent être écrites en termes deif
.la source
and
consiste à se soucier de la valeur de retour . Il ne s'agit pas nécessairement d'utiliser des effets secondaires. Si mon programme se soucie de la valeur de retour, j'utiliseand
. Si ce n'est pas le cas, je l'utilisewhen
. IOW, je l'utilisewhen
uniquement pour les effets secondaires, mais je pourrais bien utiliser unprogn
dans l'un des arguments pourand
. Il s'agit de savoir si la valeur de retour est importante, pas de savoir si elle est seule importante.and
n'est pas une fonction dans n'importe quel Lisp que je connaisse. Dans Emacs Lisp, c'est une forme spéciale, dans Common Lisp, c'est une macro, simplement parce qu'il devrait avoir un comportement de court-circuit (impossible à réaliser avec les fonctions, car elles évaluent toujours leurs arguments).and
c'est une fonction, alors que ce n'est pas le cas. Peu importe la pertinence du fait pour la question, nous devons toujours utiliser des termes corrects, c'est tout.nil
pour signifier tout "faux", "la liste vide", "vide", etc. Par exemple dans Scheme et Racket le résultat non véridique dewhen
estvoid
(c'est-à-dire "pas de sens") alors que pourand
lui est#f
("faux"). Bien que ce soit N / A pour Elisp, c'est quelque chose qu'un généraliste Lisp pourrait considérer.Permettez-moi de commencer en disant cela
(and a b)
et(when a b)
dans votre exemple, faites la même chose: le premiera
est évalué.b
est évalué sia
est vrai # .Mais
and
etwhen
sont utilisés pour différentes choses.Vous utiliseriez
(and a b)
pour renvoyer true # si LES DEUXa
etb
sont true # (ou non nul); etnil
autrement.Vous utiliseriez
(when a b)
ou pour être plus correct,lorsque vous voulez que le code "b" s'exécute si et seulement si
a
est vrai # .Voici un exemple où vous utilisez
when
etand
ensemble:Ci-dessus, la fonction
do-c
est appelée UNIQUEMENT si LES DEUXa
etb
sont vraies # .Références pour l'étude
when
section ici)and
section ici)# Toutes les références à true se réfèrent à la valeur booléenne TRUE.
la source
and
ne renvoie past
si tous ses arguments sont non nuls, mais la valeur du dernier argument.t
, je voulais dire le booléen VRAI ou non nul. Merci, je vais clarifier cela dans ma réponse.(when (and a b) c)
). De plus, la partie sur la façon dontand
etwhen
suggère que c'est en fait comment ils sont utilisés en général, mais la base même de cette question était le fait que je les vois souvent utilisés différemment (voir par exemple la réponse à laquelle j'ai lié dans ma question).