2010-09-07 9 views
6

In alcune implementazioni di Common Lisp possiamo dire che per la seguente espressioneIn clojure, is (= 'a' a) si riferisce allo 'stesso atomo'?

(eq 'a 'a) 

È true perché 'a e 'a sono i "stesso atomo".

Questo può essere a carico di attuazione, ma sembra che la frase (utilizzato in un insegnamento libro LISP popolare) presuppone che atomi dello stesso valore vengono memorizzate nella stessa posizione nella memoria.

In Java, due stringhe internate dello stesso valore sono memorizzati nella stessa posizione in memoria.

Ora Clojure su JVM eredita l'eredità di Java, ma è vero che due atomi in Clojure (su JVM) con lo stesso valore sono lo stesso atomo? (Vale a dire come funziona il meccanismo di stoccaggio atomo di Clojure?)

+2

Dialetti di Common Lisp? Cosa sono questi? Quali dialetti? Le solite implementazioni comuni di Lisp implementano ANSI Common Lisp. Ci sono dialetti di CL, ma questo non è importante, dal momento che molte persone (inclusi gli utenti di Lisp) probabilmente non ne hanno mai sentito parlare. Ma ci sono molti dialetti di Lisp. - Qualsiasi Common Lisp restituirà T per (eq 'a' a). a non è nemmeno un atomo, ma un simbolo. Anche il termine "atomo" non ha senso in questo contesto. Storicamente tutto ciò che non è una cellula è un atomo. –

+0

"In Java, due stringhe dello stesso valore sono memorizzate nella stessa posizione in memoria." - solo se sono entrambi internati. –

risposta

21

Innanzitutto, "atomo" ha un significato diverso in Clojure rispetto alla maggior parte degli altri Lisp. Vedere http://clojure.org/atoms

funzione di Clojure = utilizza valore uguaglianza based. Quindi due oggetti con valori uguali saranno = anche se sono memorizzati in posizioni diverse in memoria.

Per testare se due oggetti sono in realtà lo stesso oggetto, allo stesso indirizzo in memoria, usa la funzione identical?.

4

ti spiego la parte Common Lisp:

In Common Lisp (eq 'a' a) restituisce sempre T.

Motivo: a lettura tempo, il lettore cerca a, e per entrambi a verrà visualizzato lo stesso simbolo a. Dal momento che ogni simbolo è EQ a se stessa, l'espressione restituisce sempre T.

Questo è vero per la maggior parte dei tipi di oggetti, ma con alcune eccezioni. Numeri e caratteri, ad esempio, non sono necessari EQ in Common Lisp. La ragione di ciò è l'efficienza. Per confrontare questi se sono lo stesso numero o lo stesso carattere si può usare la funzione EQL.

6

Penso che "a e 'a saranno diversi oggetti Java sotto il cofano. Credo che questo conferma che il sospetto:

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

Se si guarda l'effettiva attuazione del Symbol in Clojure, vedrai che un simbolo è costituito da uno spazio dei nomi e un nome e quelle corde devono essere internate stringhe. Il metodo Symbol.equals() si basa sul fatto di eseguire controlli di identità su queste due stringhe, facendo affidamento su interni stringa.

4

Per aggiungere le risposte di Alex e Stuart, i Simboli in Clojure non possono essere considerati identical? ogni volta che sono = principalmente perché possono contenere metadati. Due simboli che hanno gli stessi componenti .name e .namespace ma diversi metadati saranno = ma non identical?.

cose, concettualmente, potrebbe essere disposti in modo che due simboli con gli stessi metadati, spazio dei nomi e il nome sarebbe sempre identical?, ma che è (1) due più problemi per nessun guadagno reale (dal momento che ci si ancora avere alcuni simboli = ma non identical?), (2) contrariamente all'idea che i tipi che possono contenere metadati dovrebbero normalmente essere confrontati per l'uguaglianza dei valori (a cui i metadati non contribuiscono), mentre l'uguaglianza dei puntatori effettiva dovrebbe essere riservata a situazioni speciali (per lo più coinvolgenti interop).

Si noti che le parole chiave Clojure sono un tipo separato per cui = equivale a identical?. (Quindi chiaramente non possono avere i metadati allegati.)

Problemi correlati