Quelle est la différence entre eql, eql, égal et égal, dans Common Lisp?

Quelle est la différence entre eql , eql , equal et equalp , dans Common Lisp? Je comprends que certains d’entre eux vérifient les types, certains vérifient tous les types, mais quel est celui qui? Quand est-il préférable d’utiliser que les autres?

From Common Lisp: Prédicats d’égalité

(eq xy) est vrai si et seulement si x et y sont le même object identique.

Le prédicat eql est vrai si ses arguments sont eq , ou s’il s’agit de nombres du même type ayant la même valeur ou s’il s’agit d’objects de caractère représentant le même caractère.

Le prédicat equal est vrai si ses arguments sont des objects structurellement similaires (isomorphes). En règle générale, deux objects sont égaux si et seulement si leurs représentations imprimées sont identiques.

Deux objects sont equalp s’ils sont égaux; si ce sont des caractères et satisfont un caractère égal à char, qui ignore la casse alphabétique et certains autres atsortingbuts de caractères; s’ils sont des 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 tous equalp .

Voici quelques exemples de la même page à laquelle je suis lié 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 xx)) is true. (progn (setq x '(a . b)) (eq xx)) 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 xx)) is true. (progn (setq x '(a . b)) (eql xx)) 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 xx)) is true. (progn (setq x '(a . b)) (equal xx)) 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 xx)) is true. (progn (setq x '(a . b)) (equalp xx)) 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 autres notes:

  • 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’EQ se trouve généralement une comparaison de pointeurs

Et un guide approximatif:

 A comparer avec ... Utilisez ...

 Objets / Structures EQ

 NIL EQ (mais la fonction NULL est plus concise et probablement moins chère)

 T EQ (ou juste la valeur mais vous ne vous souciez pas du type)

 Chiffres précis EQL

 Flotteurs =

 Caractères EQL ou CHAR-EQUAL

 Listes, Conses, Séquences EQ (si vous voulez exactement le même object)
                            EQUAL (si vous vous souciez des éléments)

 Chaînes EQUAL (sensible à la casse), EQUALP (insensible à la casse)
                            STRING-EQUAL (si vous lancez des symboles dans le mix)

 Arbres (listes de listes) TREE-EQUAL (avec l'argument approprié: TEST)

Notez que pour l’efficacité généralement EQ >> EQL >> EQUAL >> EQUALP.

De là et les diapositives de mon professeur

eq teste si ses arguments (représentés par le même bloc de mémoire) sont identiques ou non.

Par exemple:

(eq ‘A’ B) NIL
(eq ‘RAM’ RAM) T
(eq (contre ‘a’ b) (contre un ‘b’)); C’est parce que différents appels sont faits pour les deux cons, ils se verront évidemment atsortingbuer des morceaux de mémoire différents.

eql commence par tester si ses arguments satisfont à EQ, sinon il essaie de voir s’il s’agit de nombres du même type et des mêmes valeurs.

Par exemple:

(eql 4 4.0) NIL
(éql 4 4) T

Maintenant, notez une différence :

(eq 4.0 4.0) NIL: dépend de la plate-forme décrite 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 retourner true car il n’est pas spécifié dans la norme si une implémentation doit garder une seule copie des nombres et des caractères en mémoire, comme elle le fait avec les symboles). eq sur les chiffres et les caractères , sauf si vous savez vraiment ce que vous faites.

equal est une fonction de comparaison «plus saine». En règle générale, vous pouvez le considérer comme indiquant si deux objects se ressemblent (structurellement similaire ou isomorphe). 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)) NIL
(égal (contre ‘a’ b) (contre ‘a’ b)) T; égal est généralement vrai pour les choses qui impriment le même

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:

(égalp (contre ‘a’ b) (contre ‘a’ b)) T; identique à égal

Notez maintenant une différence

égal (4 4.0) NIL
égalp (4 4,0) T; Comme égalp traite les types de nombres de manière insensible