syntax common-lisp equality

syntax - ¿Cuál es la diferencia entre eq, eql, equal y equalp en Common Lisp?



common-lisp equality (3)

¿Cuál es la diferencia entre eq , eql , equal y equalp en Common Lisp? Entiendo que algunos de ellos verifican los tipos, algunos de ellos comprueban los tipos y todo eso, pero ¿cuál es cuál? ¿Cuándo es mejor usar uno que los otros?


Algunas notas más:

  • La mayoría de las funciones CL utilizan implícitamente EQL cuando no se especifica ninguna prueba

  • Ver también STRING-EQUAL, = y TREE-EQUAL

  • En el núcleo de EQ suele ser una comparación de puntero

Y una guía aproximada:

To compare against... Use... Objects/Structs EQ NIL EQ (but the function NULL is more concise and probably cheaper) T EQ (or just the value but then you don''t care for the type) Precise numbers EQL Floats = Characters EQL or CHAR-EQUAL Lists, Conses, Sequences EQ (if you want the exact same object) EQUAL (if you just care about elements) Strings EQUAL (case-sensitive), EQUALP (case-insensitive) STRING-EQUAL (if you throw symbols into the mix) Trees (lists of lists) TREE-EQUAL (with appropriate :TEST argument)

Tenga en cuenta que para la eficiencia generalmente EQ >> EQL >> EQUAL >> EQUALP.


De Common Lisp: Predicados de igualdad

(eq xy) es verdadero si y solo si y son el mismo objeto idéntico.

El predicado eql es verdadero si sus argumentos son eq , o si son números del mismo tipo con el mismo valor, o si son objetos de carácter que representan el mismo carácter.

El predicado equal es verdadero si sus argumentos son objetos estructuralmente similares (isomorfos). Una regla aproximada es que dos objetos son iguales si y solo si sus representaciones impresas son las mismas.

Dos objetos son equalp si son iguales; si son personajes y satisfacen caracteres iguales, lo que ignora el caso alfabético y ciertos otros atributos de los caracteres; si son números y tienen el mismo valor numérico, incluso si son de diferentes tipos; o si tienen componentes que son todos equalp .

Aquí hay algunos ejemplos de la misma página a la que he vinculado anteriormente:

(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.


Desde here y las diapositivas de mi maestro

Pruebas eq para ver si sus argumentos (representados por el mismo fragmento de memoria de la computadora) son el mismo símbolo o no.

Por ejemplo:

(eq ''A'' B) NIL
(eq ''RAM'' RAM) T
(eq (cons ''a'' b) (cons a ''b'')); Esto se debe a que se realizan diferentes llamadas para ambos contras, por lo que obviamente se asignarán diferentes fragmentos de memoria

eql primero prueba para ver si sus argumentos satisfacen EQ, si no, intenta ver si son números del mismo tipo y valores.

Por ejemplo:

(eql 4 4.0) NIL
(eql 4 4) T

Ahora note una diferencia :

(eq 4.0 4.0) NIL; Depende de la plataforma como se describe en la primera respuesta (aceptada)
(eql 4.0 4.0) T; el tipo y el valor de los argumentos es el mismo

En algunas implementaciones (eq 4.0 4.0) puede ser cierto porque no está especificado en el estándar si una implementación debe mantener solo una copia de números y caracteres en la memoria, como lo hace con los símbolos). Como regla general , no use eq en números y caracteres , a menos que realmente sepa lo que está haciendo.

equal es una función de comparación "más sana". Como regla general, puede pensar que le indica si dos objetos tienen el mismo aspecto (estructuralmente similares o isomorfos). Probablemente es el operador que desea utilizar para la igualdad general. Se comporta como eql para números, caracteres y símbolos, pero para listas (conses) y cadenas indica si sus elementos

Por ejemplo:

(igual a 4 4) T
(igual (+ 2 2) 4) T

Ahora note una diferencia

(eql (contra ''a'' b) (contra ''a'' b)) NIL
(igual (contra ''a'' b) (contra ''a'' b)) T; igual suele ser cierto para las cosas que imprimen el mismo

equalp es igual, simplemente más avanzado. La comparación de números es insensible al tipo. La comparación de caracteres y cadenas no distingue entre mayúsculas y minúsculas.

Por ejemplo:

(equalp (cons ''a'' b) (cons ''a'' b)) T; lo mismo que igual

Ahora note una diferencia

igual (4 4.0) NIL
equalp (4 4.0) T; Como igualdad, trata los números de forma insensible