2011-12-19 12 views
14

Che cosa la sintassi, i due punti precedenti variabile in Common Lisp, intendo? Ho visto programmi con questo, e presenterò qui un codice di esempio, con un ampio set di funzioni.Perché due punti precedono le variabili in Common Lisp

(defun expand (successorf node) 
    (mapcar (lambda (action-state-cost) 
      (let ((action (car action-state-cost)) 
       (state (cadr action-state-cost)) 
       (cost (caddr action-state-cost))) 
      (make-node :state state :parent node 
         :action action :path-cost (+ (node-path-cost node) cost) 
         :depth (1+ (node-depth node))) 
      )) 
     (funcall successorf (node-state node)) 
    )) 

risposta

18

Non sono variabili, in realtà; quelle sono parole chiave. Sono un tipo speciale di token efficiente, simile agli "atomi" in altre lingue. È un modo pratico e integrato per passare i parametri con nome (e, quasi sempre, facoltativi) in una chiamata di funzione.

http://www.gigamonkeys.com/book/functions.html descrive la sintassi delle chiamate di funzione.

27

chiave Simboli

:foo è un simbolokeyword.

  • internati e esportati dal pacchetto KEYWORD
  • tenuto costantemente a sé

Uso

simboli chiave vengono utilizzati quando si ha bisogno la combinazione delle seguenti caratteristiche:

  • un simbolo è la giusta struttura dei dati
  • simboli con lo stesso nome deve essere unico (da loro internamento in un pacchetto) -> pacchetto KEYWORD
  • diversi pacchetti non sono necessari o voluto -> pacchetto KEYWORD
  • scrivere il simbolo dovrebbe essere facile da non aver bisogno di citarli ->:foo meglio di ':foo
  • la capacità di agire come non è necessaria una variabile con valori diversi ->:foo viene valutato come :foo se stessa e solo per :foo

In Common Lisp generalmente simboli possono essere in un pacchetto (una specie di spazio dei nomi).

Un simbolo non identificato bar in un pacchetto foo è scritto come foo::bar. Il doppio punto è tra il nome del pacchetto e il nome del simbolo.

Un simbolo esportato poi è scritto come foo:bar. Viene usato un singolo colon.

Se il simbolo è disponibile nel pacchetto corrente, allora è scritto come bar senza il pacchetto.

Il pacchetto KEYWORD

V'è un pacchetto speciale chiamato KEYWORD. Un simbolo bar in quel pacchetto è semplicemente e sempre scritto come :bar.

Esempi

Questi simboli delle parole chiave hanno anche queste interessanti proprietà: i simboli vengono esportati automaticamente dal pacchetto KEYWORD (così keyword::bar, keyword:bar, ::bar e :bar sono tutti lo stesso simbolo) e si valutano a se stessi:

CL-USER 5 > :bar 
:BAR 

CL-USER 6 > (describe :bar) 

:BAR is a SYMBOL 
NAME   "BAR" 
VALUE   :BAR 
FUNCTION  #<unbound function> 
PLIST   NIL 
PACKAGE  #<The KEYWORD package, 0/4 internal, 5830/8192 external> 

CL-USER 7 > (eq 'keyword::bar ':bar) 
T 

CL-USER 8 > (eq :bar ':bar) ; quoted or unquoted, each subform evaluates to :bar 
T 

Uso

simboli chiave sono usati per esempio come i nomi in argomenti con nome:

(defun foo (&key bar) (+ bar 10)) 

(foo :bar 7) 

Tipicamente essi sono utilizzati anche in argomenti di istanza e costruzione della struttura.

(defstruct node state parent action) 

DEFSTRUCT è una macro Common Lisp e genera diverse funzioni. Uno di loro è una funzione MAKE-NODE, che può essere utilizzato come:

(make-node :state 'open 
      :parent some-parent 
      :action an-action) 

Nota: a volte i dati possono anche essere una parola chiave. Ad esempio, nel modulo di cui sopra, lo Stato potrebbe essere :open e non open:

(make-node :state :open 
      :parent some-parent 
      :action an-action) 
+0

Lei scrive: "Un simbolo di ** ** esportato ... è scritto come' foo:. Bar' * Un singolo colon viene utilizzato * .. "e anche" i simboli [parola chiave] sono ** esportati automaticamente **, "ma il tuo esempio mostra' (eq 'keyword :: bar': bar) '. Perché usi il doppio punto se le parole chiave vengono sempre esportate? È possibile utilizzare '::' con simboli sia esportati che non esportati? –

+0

@GlennSlayden Sì, ogni simbolo internato, esportato o non esportato, può essere scritto come pacchetto :: nome. Solo i simboli esportati possono essere scritti come pacchetto: nome. Solo i simboli delle parole chiave possono essere scritti come: nome. –

+0

Per completezza, che dire ':: bar'? Fa ancora riferimento al pacchetto 'KEYWORD', o sarebbe ora un'altra forma di globale? Mi dispiace per essere un principiante LISP. –