2010-09-07 14 views
6

En algunas implementaciones de Common Lisp podemos decir que para la siguiente expresiónEn clojure, ¿(= 'a' a) se refiere al 'mismo átomo'?

(eq 'a 'a) 

Es true porque 'a y 'a son el "mismo átomo".

Esto puede ser dependiente de la implementación, pero parece que la frase (utilizado en un libro popular enseñanza LISP) supone que los átomos del mismo valor se almacenan en la misma ubicación en la memoria.

En Java, dos cadenas internadas del mismo valor se almacenan en la misma ubicación en la memoria.

Ahora Clojure en la JVM hereda el legado de Java, pero ¿es cierto que dos átomos en Clojure (en JVM) que tienen el mismo valor son el mismo átomo? (Es decir, ¿cómo funciona el mecanismo de almacenamiento átomo de Clojure?)

+2

¿Dialectos de Common Lisp? ¿Que son estos? ¿Qué dialectos? Las implementaciones de Common Lisp habituales implementan ANSI Common Lisp. Hay dialectos de CL, pero eso no es importante, ya que la mayoría de las personas (incluidos los usuarios de Lisp) probablemente nunca han oído hablar de ellos. Pero hay muchos dialectos de Lisp. - Cualquier Common Lisp devolverá T para (eq 'a' a). a tampoco es un átomo, sino un símbolo. El término 'átomo' tampoco tiene sentido en este contexto. Históricamente, todo lo que no es una celda de cons es un átomo. –

+0

"En Java, dos cadenas del mismo valor se almacenan en la misma ubicación en la memoria". - solo si ambos están internados –

Respuesta

21

En primer lugar, "átomo" tiene un significado diferente en Clojure que en la mayoría de los otros Lisps. Ver http://clojure.org/atoms

La función de Clojure = utiliza valor-igualdad basada. Por lo tanto, dos objetos con valores iguales serán =, incluso si están almacenados en diferentes lugares de la memoria.

Para probar si dos objetos son en realidad el mismo objeto, en la misma dirección en la memoria, utilice la función identical?.

4

Voy a explicar la parte Common Lisp:

En Common Lisp (eq 'a' a) devuelve siempre T.

Motivo: en lectura tiempo, el lector busca a, y para ambos a buscará el mismo símbolo a. Dado que cualquier símbolo es EQ a sí misma, la expresión devuelve siempre T.

Esto es cierto para la mayoría de tipos de objetos, pero con algunas excepciones. Los números y los caracteres, por ejemplo, no son necesarios para EQ en Common Lisp. La razón de eso es la eficiencia. Para compararlos, si son el mismo número o el mismo carácter, uno puede usar la función EQL.

6

Creo que 'a y' a van a ser diferentes objetos de Java bajo el capó. Creo que esto confirma que la sospecha:

user> (def foo 5) 
#'user/foo 
user> (System/identityHashCode 'foo) 
578999228 
user> (System/identityHashCode 'foo) 
1724482638 

Si nos fijamos en la aplicación real de Symbol en Clojure, verá que un símbolo consiste en un espacio de nombres y un nombre y esas cadenas deben ser internada cuerdas. El método Symbol.equals() se basa en realizar comprobaciones de identidad en esas dos cadenas, dependiendo de la cadena interna.

4

Para agregar a las respuestas de Alex y Stuart, los símbolos en Clojure no pueden ser identical? cuando son = principalmente porque pueden llevar metadatos. Dos símbolos que tienen los mismos componentes .name y .namespace pero metadatos diferentes serán = pero no identical?.

cosas posiblemente podrían estar dispuestos de manera que dos símbolos con los mismos metadatos, espacio de nombres y el nombre siempre estarían identical?, pero que es (1) dos mucha molestia por ninguna ganancia real (ya que usted todavía tiene algunos símbolos = pero no identical?), (2) contrario a la idea de que los tipos que pueden llevar metadatos normalmente deben compararse para la igualdad de valores (a los que los metadatos no contribuyen), mientras que la igualdad real del puntero debe reservarse para situaciones especiales (principalmente con interoperabilidad).

Tenga en cuenta que Clojure Las palabras clave son un tipo separado para el que = es de hecho equivalente a identical?. (Entonces, claramente no pueden tener metadatos adjuntos).

Cuestiones relacionadas