2011-12-19 8 views
14

¿Qué significa la sintaxis, los dos puntos anteriores a la variable en Common Lisp? He visto programas con eso, y voy a presentar algunos ejemplos de código aquí, de un gran conjunto de funciones.Por qué los dos puntos preceden a las variables en 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)) 
    )) 

Respuesta

18

No son variables, en realidad; esas son palabras clave. Son un tipo especial de token eficiente, similar a "átomos" en otros idiomas. Es una forma conveniente e integrada de pasar parámetros nombrados (y, casi siempre, opcionales) en una llamada a función.

http://www.gigamonkeys.com/book/functions.html describe la sintaxis de las llamadas a funciones.

27

Símbolos palabra clave

:foo es un símbolokeyword.

  • internados en y se exportan desde el paquete KEYWORD
  • obligado constantemente a sí mismo

Uso

símbolos de palabras clave se usan cuando se necesita la combinación de las siguientes propiedades:

  • un símbolo es la estructura correcta de datos
  • símbolos con el mismo nombre debe ser único (por internar en un paquete) -> paquete KEYWORD
  • paquetes diferentes, no se necesitan o quieren -> paquete KEYWORD
  • escribir el símbolo debe ser fácil al no tener que citarlos ->:foo mejor que ':foo
  • la capacidad de actuar como no se necesita una variable con diferentes valores ->:foo evalúa a :foo sí y sólo a :foo

En Common Lisp, los símbolos generalmente pueden estar en un paquete (tipo de espacio de nombres).

Un símbolo no exportado bar en un paquete foo se escribe como foo::bar. El doble punto está entre el nombre del paquete y el nombre del símbolo.

Un símbolo exportado se escribe como foo:bar. Se usa un solo colon.

Si el símbolo está disponible en el paquete actual, se escribe como bar sin el paquete.

El paquete KEYWORD

hay un paquete especial llamado KEYWORD. Un símbolo bar en ese paquete se escribe simple y siempre como :bar.

Ejemplos

Estos símbolos de palabras clave también tienen estas propiedades interesantes: los símbolos se exportan de forma automática desde el paquete KEYWORD (por lo keyword::bar, keyword:bar, ::bar y :bar son todos el mismo símbolo) y se evalúan a sí mismos:

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

símbolos de palabras clave se usan por ejemplo como nombres en argumentos con nombre:

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

(foo :bar 7) 

Típicamente también se utilizan en argumentos de instancia y construcción de la estructura.

(defstruct node state parent action) 

DEFSTRUCT es una macro Common Lisp y genera varias funciones. Uno de ellos es una función MAKE-NODE, que se puede utilizar como:

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

Nota: a veces los datos también podrían ser una palabra clave. Por ejemplo, en forma anterior, el estado podría ser :open y no open:

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

Usted escribe: "Un símbolo ** ** ... exportado se escribe como 'foo:. Bar' sean * Un solo dos puntos se utiliza * .. "y también" los símbolos [de palabras clave] ** se exportan automáticamente ** ", pero su ejemplo muestra' (eq 'palabra clave :: barra': barra) '. ¿Por qué usa el doble punto si las palabras clave siempre se exportan? ¿Puede '::' usarse con símbolos exportados y no exportados? –

+0

@GlennSlayden Sí, cada símbolo interno, exportado o no exportado, se puede escribir como paquete :: nombre. Solo los símbolos exportados se pueden escribir como paquete: nombre. Solo los símbolos de palabras clave se pueden escribir como: nombre. –

+0

Para completar, ¿qué pasa con ':: bar'? ¿Todavía se refiere al paquete 'KEYWORD', o sería ahora alguna otra forma de global? Perdón por ser un novato de LISP. –