2009-10-06 10 views
111

Ho una conoscenza passata di altri Lisps (in particolare Scheme) da lungo tempo. Recentemente ho letto su Clojure. Vedo che ha sia "simboli" che "parole chiave". Simboli con cui ho familiarità, ma non con parole chiave.Perché Clojure ha "parole chiave" oltre a "simboli"?

Gli altri Lisp hanno parole chiave? In che modo le parole chiave sono diverse da simboli diversi dalla notazione differente (ad esempio: due punti)?

+0

Vedere anche: [in Clojure, perché stringhe, parole chiave e simboli?] (Http://stackoverflow.com/q/11655080/405550) – Zaz

risposta

119

Ecco lo Clojure documentation per Parole chiave e simboli.

Le parole chiave sono identificativi simbolici che valutano se stessi. Forniscono test di uguaglianza molto veloci ...

I simboli sono identificatori che vengono normalmente utilizzati per riferirsi a qualcos'altro. Possono essere utilizzati nei moduli del programma per fare riferimento ai parametri delle funzioni, lasciare associazioni, nomi di classi e vars globali ...

Le parole chiave sono generalmente utilizzate come "stringhe costanti" leggere, ad es. per le chiavi di una mappa hash o i valori di spedizione di un multimetodo. I simboli sono generalmente usati per denominare le variabili e le funzioni ed è meno comune manipolarli come oggetti direttamente tranne che nei macro e così via. Ma non c'è nulla che ti impedisca di usare un simbolo ovunque usi una parola chiave (se non ti dispiace citarli tutto il tempo).

Il modo più semplice per vedere la differenza è leggere Keyword.java e Symbol.java nella fonte Clojure. Ci sono alcune ovvie differenze di implementazione. Ad esempio, un simbolo in Clojure può avere metadati e una parola chiave non può.

In aggiunta alla sintassi dei singoli punti, è possibile utilizzare un doppio punto due per creare una parola chiave qualificata per lo spazio dei nomi.

user> :foo 
:foo 
user> ::foo 
:user/foo 

Comune Lisp ha parole chiave, così come Ruby e altre lingue. Sono leggermente diversi in quelle lingue, naturalmente. Alcune differenze tra parole chiave Common Lisp e Clojure:

  1. Le parole chiave in Clojure non sono simboli.

    user> (symbol? :foo) 
    false 
    
  2. Parole non appartengono a qualsiasi spazio dei nomi meno che non li qualificano: (. Grazie per avermi dato Rainer Joswig idee di cose da guardare)

    user> (namespace :foo) 
    nil 
    user> (namespace ::foo) 
    "user" 
    

+9

Questo spiega quali sono le differenze, ma non perché sono necessari due diversi costrutti. Clojure non è riuscito a creare qualcosa con l'unione delle funzionalità di Keyword e Symbol? – mtnygard

+20

Le parole chiave sono leggere e hanno una sintassi comoda, penso che sia tutto quello che c'è da fare. Il linguaggio funzionerebbe senza di loro ma sono belli da usare e sono molto usati. Non puoi avere un'unione delle loro abilità perché le parole chiave sono sempre autovalutanti (cioè non puoi usarle come nomi di variabili o di funzioni) ei simboli in generale non possono essere sempre auto-valutanti. –

+1

Sembra che le parole chiave siano più utili come chiavi nelle hashmaps ecc. Poiché non cambiano una volta valutate: '(eval (eval ': a))' vs '(eval (eval' 'a))'. Ci sono altri vantaggi? Per quanto riguarda le prestazioni, sono identici? – kristianlm

5

Le parole chiave sono simboli che valutano se stessi, quindi non è necessario ricordarsi di citarli.

+5

È così? Digitando: piuttosto che "non sembra una grande vittoria, specialmente da quando: è un tasto di pressione in più sulla maggior parte delle tastiere. –

+8

Beh, è ​​molto più che il personaggio, davvero. Le parole chiave rimangono parole chiave dopo la valutazione, mentre i simboli vengono valutati in base a ciò a cui si collegano. È più simile a una differenza semantica, perché sono tipicamente utilizzati per scopi diversi. –

+12

Le parole chiave non sono simboli in Clojure –

26

Common Lisp ha simboli di parole chiave.

Anche le parole chiave sono simboli.

(symbolp ':foo) -> T 

Ciò che rende speciali le parole chiave:

  • : foo viene analizzato dal lettore Common Lisp come la parola simbolo :: foo
  • parole chiave valutano a se stessi:: foo ->: foo
  • il pacchetto home di simboli di parole chiave è il pacchetto KEYWORD: parola chiave: foo ->: foo
  • le parole chiave vengono esportate dal pacchetto KEYWORD
  • parole chiave sono costanti, non è consentito assegnare un valore diverso

Altrimenti le parole chiave sono simboli ordinari. Le parole chiave possono quindi denominare funzioni o disporre di elenchi di proprietà.

Ricorda: in Common i simboli Lisp appartengono ad un pacchetto. Questo può essere scritto come:

  • foo, quando il simbolo è accessibile nel pacchetto corrente
  • foo: bar, quando il FOO simbolo viene esportato dalla barra pacchetto
  • foo :: bar, quando il il simbolo FOO è nel pacchetto BAR

Per simboli di parole chiave che significa che: foo, parola chiave: foo e parola chiave :: foo sono tutti lo stesso simbolo. Pertanto, le ultime due notazioni non vengono solitamente utilizzate.

Quindi: foo è appena analizzato per essere nel pacchetto KEYWORD, assumendo che non dare il nome del pacchetto prima del nome del simbolo significhi per impostazione predefinita il pacchetto KEYWORD.

2

: le parole chiave vengono trattate in modo speciale da molte raccolte, consentendo una sintassi molto comoda.

(:user-id (get-users-map)) 

è lo stesso di

((get-users-map) :user-id) 

questo rende le cose un po 'più flexable

+19

Ciò vale anche per i simboli, ('a {' a 1 'b 2}) => 1 e ({' a 1 'b 2}' b) => 2. – Jonas

3

Per le parole chiave, i valori hash vengono calcolati e memorizzati nella cache quando la parola è prima costruito. Quando si cerca una parola chiave come chiave hash, semplicemente restituisce il valore hash precalcolato. Per le stringhe e i simboli, l'hash è ricalcolato su ogni ricerca.

Perché le stesse parole chiave identificate sono sempre identiche, contengono i propri valori hash. Poiché la ricerca in mappe e insiemi è fatta da chiavi hash, questo aumenta la capacità di ricerca in caso di numerose ricerche, non nella ricerca stessa.

Problemi correlati