Quelle est la différence entre eq
, eql
, equal
et equalp
, en Common Lisp? Je comprends que certains d'entre eux vérifient les types, certains vérifient les types et tout cela, mais lequel est lequel? Quand est-il préférable d'utiliser l'un que les autres?
De LISP commun: prédicats d'égalité
(eq x y)
est vrai si et seulement six
ety
sont le même objet identique.Le prédicat
eql
est vrai si ses arguments sonteq
, ou si ce sont des nombres du même type avec la même valeur, ou si ce sont des objets de caractère qui représentent le même caractère.Le prédicat
equal
est vrai si ses arguments sont des objets structurellement similaires (isomorphes). Une règle générale est que deux objets sont égaux si et seulement si leurs représentations imprimées sont les mêmes.Deux objets sont
equalp
s'ils sont égaux; s'ils sont des caractères et satisfont au caractère égal, ce qui ignore la casse alphabétique et certains autres attributs des caractères; s'il s'agit de nombres et ont la même valeur numérique, même s'ils sont de types différents; ou s'ils ont des composants qui sont tousequalp
.
Voici quelques exemples de la même page que j'ai liée à ci-dessus:
(eq 'a 'b) is false.
(eq 'a 'a) is true.
(eq 3 3) might be true or false, depending on the implementation.
(eq 3 3.0) is false.
(eq 3.0 3.0) might be true or false, depending on the implementation.
(eq #c(3 -4) #c(3 -4))
might be true or false, depending on the implementation.
(eq #c(3 -4.0) #c(3 -4)) is false.
(eq (cons 'a 'b) (cons 'a 'c)) is false.
(eq (cons 'a 'b) (cons 'a 'b)) is false.
(eq '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eq x x)) is true.
(progn (setq x '(a . b)) (eq x x)) is true.
(eq #\A #\A) might be true or false, depending on the implementation.
(eq "Foo" "Foo") might be true or false.
(eq "Foo" (copy-seq "Foo")) is false.
(eq "FOO" "foo") is false.
(eql 'a 'b) is false.
(eql 'a 'a) is true.
(eql 3 3) is true.
(eql 3 3.0) is false.
(eql 3.0 3.0) is true.
(eql #c(3 -4) #c(3 -4)) is true.
(eql #c(3 -4.0) #c(3 -4)) is false.
(eql (cons 'a 'b) (cons 'a 'c)) is false.
(eql (cons 'a 'b) (cons 'a 'b)) is false.
(eql '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eql x x)) is true.
(progn (setq x '(a . b)) (eql x x)) is true.
(eql #\A #\A) is true.
(eql "Foo" "Foo") might be true or false.
(eql "Foo" (copy-seq "Foo")) is false.
(eql "FOO" "foo") is false.
(equal 'a 'b) is false.
(equal 'a 'a) is true.
(equal 3 3) is true.
(equal 3 3.0) is false.
(equal 3.0 3.0) is true.
(equal #c(3 -4) #c(3 -4)) is true.
(equal #c(3 -4.0) #c(3 -4)) is false.
(equal (cons 'a 'b) (cons 'a 'c)) is false.
(equal (cons 'a 'b) (cons 'a 'b)) is true.
(equal '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equal x x)) is true.
(progn (setq x '(a . b)) (equal x x)) is true.
(equal #\A #\A) is true.
(equal "Foo" "Foo") is true.
(equal "Foo" (copy-seq "Foo")) is true.
(equal "FOO" "foo") is false.
(equalp 'a 'b) is false.
(equalp 'a 'a) is true.
(equalp 3 3) is true.
(equalp 3 3.0) is true.
(equalp 3.0 3.0) is true.
(equalp #c(3 -4) #c(3 -4)) is true.
(equalp #c(3 -4.0) #c(3 -4)) is true.
(equalp (cons 'a 'b) (cons 'a 'c)) is false.
(equalp (cons 'a 'b) (cons 'a 'b)) is true.
(equalp '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equalp x x)) is true.
(progn (setq x '(a . b)) (equalp x x)) is true.
(equalp #\A #\A) is true.
(equalp "Foo" "Foo") is true.
(equalp "Foo" (copy-seq "Foo")) is true.
(equalp "FOO" "foo") is true.
Quelques notes supplémentaires:
La plupart des fonctions CL utilisent implicitement EQL quand aucun test n'est spécifié
Voir aussi STRING-EQUAL, = et TREE-EQUAL
Au cœur de l'égalisation se trouve généralement une comparaison de pointeurs
Et un guide approximatif:
Pour comparer avec ... Utilisez ... Objets/Structures EQ NIL EQ (mais la fonction NULL est plus concise et probablement moins cher) T EQ (ou juste la valeur, mais vous ne vous souciez pas du type) Numéros précis EQL Flotteurs = Caractères EQL ou CHAR-EQUAL Listes, Conses, Séquences EQ (si vous voulez exactement le même objet) EQUAL (si vous vous souciez uniquement des éléments) Chaînes EQUAL (sensible à la casse), EQUALP (ne respectant pas la casse) STRING-EQUAL (si vous lancez des symboles dans le mix.) Arbres (listes de listes) TREE-EQUAL (avec l'argument TEST approprié)
Notez que pour l'efficacité généralement EQ >> EQL >> EQUAL >> EQUALP.
De ici et les diapositives de mon professeur
eq teste pour voir si ses arguments (représentés par le même bloc de mémoire d'ordinateur) sont le même symbole ou non.
Par exemple:
(eq "A" B) NUL
(eq ‘RAM’ RAM) T
(eq (contre 'a' b) (contre a 'b')); Ceci est dû au fait que différents appels sont effectués pour les deux inconvénients, de sorte qu'ils se verront évidemment allouer différents morceaux de mémoire
eql teste d'abord si ses arguments satisfont EQ, sinon, il essaie de voir s'il s'agit de nombres du même type et de mêmes valeurs.
Par exemple:
(eql 4 4.0) NUL
(eql 4 4) T
Notez maintenant une différence :
(eq 4.0 4.0) NIL; Dépend de la plateforme comme décrit dans la première réponse (acceptée)
(eql 4.0 4.0) T; le type et la valeur des arguments sont les mêmes
Sur certaines implémentations (eq 4.0 4.0) peut renvoyer true car il n'est pas spécifié dans la norme si une implémentation doit conserver une seule copie des nombres et des caractères en mémoire, comme elle le fait avec les symboles). n'utilisez pas d'égalisation sur les chiffres et les caractères , à moins que vous sachiez vraiment ce que vous faites.
égal est une fonction de comparaison "plus saine". En règle générale, vous pouvez penser que cela vous indique si deux objets se ressemblent (structurellement similaires ou isomorphes). C'est probablement l'opérateur que vous souhaitez utiliser pour l'égalité générale. Il se comporte comme eql pour les nombres, les caractères et les symboles, mais pour les listes (conses) et les chaînes il indique si leurs éléments
Par exemple:
(égal 4 4) T
(égal (+ 2 2) 4) T
Notez maintenant une différence
(eql (contre 'a' b) (contre 'a' b)) NUL
(égal (contre 'a' b) (contre 'a' b)) T; égal est généralement vrai pour les choses qui s'impriment de la même façon
equalp est comme égal, juste plus avancé. La comparaison des nombres est insensible au type. La comparaison des caractères et des chaînes est insensible à la casse.
Par exemple:
(equalp (contre 'a' b) (contre 'a' b)) T; identique à égal
Notez maintenant une différence
égal (4 4,0) NUL
equalp (4 4,0) T; Comme equalp traite les nombres de manière insensible