J'ai ce qui suit:
(setq some-variable "less")
Je ne comprends pas pourquoi je dois utiliser la citation unique avec boundp
mais pas avec bound-and-true-p
.
Exemple 1:
(when (boundp 'some-variable)
(message "some-variable is %s" some-variable))
Résultat:
"une variable est moins"
Exemple 2a:
(when (bound-and-true-p some-variable) ;; Note that using single-quote causes error
(message "some-variable is %s" some-variable))
Résultat:
"une variable est moins"
Exemple 2b:
(when (bound-and-true-p 'some-variable) ;; Note that using single-quote causes error
(message "some-variable is %s" some-variable))
Résultat:
et: Argument de type incorrect: symbolp, (citez une variable)
setq
signifieset quoted
et était à l'origine une macro qui s'est développée(set 'some-variable "less")
. En général, Elisp n'est pas terriblement cohérent à propos des arguments entre guillemets et sans guillemets, mais toute fonction (pas une macro) qui doit interagir avec une variable au lieu d'une valeur prendra son argument entre guillemets (setq
étant une exception majeure).bound-and-true-p
est une macro stupide. Ou plutôt, son nom est stupide. 99,99% du temps lorsque vous voulez le faire,(and (boundp 'FOO) FOO)
vous utilisez la valeur deFOO
. Vous ne le faites pas simplement pour obtenir une valeur de vérité. (1) La macro n'est pas nécessaire - le code qu'elle remplace est trivial et petit. (2) Le nom est trompeur - il s'agit de la valeur de la variable, pas seulement de tester si la valeur de la variable l'est ou nonnil
.Réponses:
Réponse courte
Si vous essayez d'utiliser la variable elle-même, utilisez
'some-variable
. Si vous essayez d'utiliser la valeur stockée dans la variable, utilisezsome-variable
.Explication
Pour la définition du manuel, veuillez consulter le manuel .
'
et les(quote ...)
deux remplissent le même rôle dans emacs-lisp.Le but est de transmettre la forme non évaluée au milieu environnant plutôt que de l'évaluer.
Dans votre exemple, supposons que nous avions les éléments suivants plus haut
Ensuite, l'évaluation se déroule comme suit:
Alors que sans devis:
Lisp évalue les formulaires lorsqu'ils sont atteints, en citant le formulaire que vous empêchez l'évaluation afin que la variable réelle (ou la liste ou le nom de la fonction) soit transmise.
la source
bound-and-truep
et la question était de savoir pourquoi dois-je citer lors de l'utilisation,boundp
mais pas lors de l'utilisationbound-and-truep
.boundp
exiger un symbole (non évalué) etbound-and-truep
avoir besoin de la valeur de la variable dans les puces (édité après la réponse initiale)Un symbole qui est en position non fonctionnelle est traité comme le nom d'une variable. In
(function variable)
function
est en position de fonction (après la parenthèse ouvrante) etvariable
ne l'est pas. Sauf si les variables explicitement citées sont remplacées par leurs valeurs.Si vous deviez écrire
(boundp my-variable)
cela signifierait "est le symbole qui est stocké dans la valeur de la variablemy-variable
liée en tant que variable" et non "est le symbolemy-variable
lié en tant que variable.Alors pourquoi
bound-and-truep
se comporte-t-il différemment?Il s'agit d'une macro et les règles d'évaluation normales (fonction) ne s'appliquent pas ici, les macros sont libres de décider si et quand leurs arguments sont évalués. Ce que les macros font réellement, c'est d'une manière ou d'une autre de transformer les arguments et de renvoyer le résultat sous forme de liste, qui est ensuite évaluée. La transformation et l'évaluation finale se produisent à différents moments, appelés temps de macro-expansion et temps d'évaluation.
Voici à quoi
bound-and-true-p
ressemble la définition de :Cela utilise des macros de lecteur qui sont différentes des macros lisp (plus d'informations ci-dessous). Pour ne pas compliquer cela, nous ne devons pas utiliser de macros de lecture:
Si vous écrivez
qui est d'abord "traduit" en
et ensuite cela est évalué en retournant
nil
ifmy-variable
n'est pasboundp
ou bien la valeur demy-variable
(qui bien sûr peut aussi êtrenil
).Vous avez peut-être remarqué que l'extension n'était pas
comme on aurait pu s'y attendre.
quote
est une forme spéciale, pas une macro ou une fonction. Comme les macros, les formulaires spéciaux peuvent faire n'importe quoi avec leurs arguments. Cette forme spéciale particulière renvoie simplement son argument, ici un symbole, au lieu de la valeur variable du symbole. C'est en fait le seul but de ce formulaire spécial: empêcher l'évaluation! Les macros ne peuvent pas le faire par elles-mêmes, elles doivent les utiliserquote
pour le faire.Alors quoi de neuf
'
? Il s'agit d'une macro de lecture qui, comme mentionné ci-dessus, n'est pas la même chose qu'une macro lisp . Alors que les macros sont utilisées pour transformer le code / les données, les macros du lecteur sont utilisées plus tôt lors de la lecture du texte afin de transformer ce texte en code / données.est une forme abrégée pour
`
utilisé dans la définition réelle debound-and-true-p
est également une macro de lecture. S'il cite un symbole comme dans,`symbol
il est équivalent à'symbol
, mais quand est utilisé pour citer une liste comme dans,`(foo bar ,baz)
il se comporte différemment dans la mesure où les formulaires préfixés,
sont évalués.est équivalent à
Cela devrait répondre à la question de savoir pourquoi les symboles non cités sont parfois évalués (remplacés par leurs valeurs) et parfois non; les macros peuvent être utilisées
quote
pour empêcher l'évaluation d'un symbole.Mais pourquoi
bound-and-true-p
une macroboundp
ne l'est-elle pas? Nous devons être en mesure de déterminer si des symboles arbitraires, qui ne sont pas connus avant l'exécution, sont liés en tant que symboles. Cela ne serait pas possible si l'boundp
argument était automatiquement cité.bound-and-true-p
est utilisé pour déterminer si une variable connue est définie et si c'est le cas, utilisez sa valeur. Ceci est utile si une bibliothèque a une dépendance facultative sur une bibliothèque tierce comme dans:bound-and-true-p
pourrait être défini comme une fonction et nécessiter la citation de l'argument, mais parce qu'il est destiné aux cas où vous savez à l'avance quelle variable vous vous souciez d'une macro a été utilisée pour vous éviter d'avoir à taper le'
.la source
À partir du code source de
boundp
:boundp
attend asymbol
comme entrée.'some-variable
est un symbole de la variablesome-variable
.À partir du code source de
bound-and-true-p
:bound-and-true-p
attend avariable
comme entrée.À l'intérieur de la
bound-and-true-p
macro, il obtient le symbole en faisant(quote ,var)
. Donc, si l'entrée estsome-variable
, se(quote ,var)
traduira par'some-variable
.Mais quand je donne l'entrée
'some-variable
àbound-and-true-p
, j'obtiens l'erreur:and: Wrong type argument: symbolp, (quote some-variable)
parce que la macro n'attend PAS de symbole ('some-variable
) à l'entrée.la source
''symbol
a du sens. Ça veut dire(quote (quote symbol))
. La raison pour laquelle vous obtenez une erreur est que ce n'est pas un argument valide pourboundp
.