2011-02-18 13 views
11

Me encanta la idea de los lenguajes basados ​​en imágenes, y últimamente he estado jugando con Common Lisp a través de sbcl. He leído en algunos lugares cómo a través de la posibilidad de guardar y cargar una imagen de la máquina virtual, puede desarrollar una aplicación o conjunto de aplicaciones que se ejecutan en esa imagen.Evolucionando una imagen de lisp

Obtengo cómo cargar código en una imagen y ponerla en funcionamiento, el fango hace que este tipo de cosas sea muy agradable, pero mi pregunta es esta: ¿cómo puedo saber qué funciones están definidas en una imagen? Digamos que quiero actualizar una función días o meses después de que se haya ejecutado y no recuerdo el nombre. ¿Hay alguna forma de acceder al código o solo los nombres de las funciones definidas en una imagen?

Ahora, escribo el código en el código fuente y lo cargo a través del repl, así que tengo una copia allí, pero parece que esto sería una característica obvia.

Respuesta

13

Common Lisp tiene la idea de paquetes. Los paquetes son una especie de registro de símbolos y se utilizan como espacios de nombres para símbolos. Puede solicitar Common Lisp para obtener una lista de todos los paquetes.

CL-USER 1 > (list-all-packages) 
(#<The SQL-COMMON package, 0/4 internal, 28/32 external> 
#<The LOOP package, 245/256 internal, 3/4 external> 
#<The COMM package, 0/4 internal, 940/1024 external> 
#<The REG package, 41/64 internal, 0/4 external> 
...) 

Cada paquete almacena los símbolos internos en alguna estructura de datos. Puede preguntar a Common Lisp qué símbolos están internados en un paquete.

CL-USER 2 > (loop for symbol being 
       each external-symbol in (find-package "COMMON-LISP") 
      collect symbol) 
(MAKE-ARRAY INVOKE-DEBUGGER STRING-TRIM ...) 

Para hacerlo más fácil, Common Lisp proporciona funciones APROPOS y APROPOS-LIST.

CL-USER 3 > (apropos "MAKE-LOCK") 
MP::INTERNAL-MAKE-LOCK (defined) 
MP:MAKE-LOCK (defined) 
WWW-UTILS:MAKE-LOCK (defined) 
MAKE-LOCK 
RESOURCES::MAKE-LOCK (defined) 
MINIPROC:MAKE-LOCK (defined) 

Las funciones, las clases, etc. usan símbolos como su identificador. También puede pedir un símbolo, cuya función denota.

CL-USER 4 > (symbol-function 'www-utils:make-lock) 
#<Function WWW-UTILS:MAKE-LOCK 41E006A69C> 

A veces, un Lisp común también registra la definición de funciones. Entonces la función FUNCTION-LAMBDA-EXPRESSION se puede usar para recuperar 'it'.

CL-USER 5 > (defun foo (a) (* (sin a) a)) 
FOO 

CL-USER 6 > (pprint (function-lambda-expression 'foo)) 

(LAMBDA (A) 
    (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 41403151C3>)) 
    (DECLARE (LAMBDA-NAME FOO)) 
    (* (SIN A) A)) 

Pero por lo general las implementaciones de Lisp hoy comunes no utilizan las definiciones grabadas, pero grabar la ubicación de la fuente para cada construcción Lisp.

La mayoría de las implementaciones de Lisp comunes pueden rastrear las ubicaciones de origen de una manera específica de implementación.

El estándar Common Lisp define una función ED.

CL-USER 7 > (ed 'www-utils:make-lock) 

Llama a un editor (interno o externo) y debe abrir el código fuente para esa función. Para que funcione, Common Lisp necesita realizar un seguimiento de la ubicación de origen para cada función. A continuación, el editor debe tener acceso a esa fuente. A veces, la ubicación registrada es una ruta absoluta /Users/joswig/lisp/utils.lisp. Si el editor desea abrir ese archivo, debe ser accesible. Pero también es posible utilizar rutas de acceso lógicas como http: server; utils.lisp. Esto se traduce en un nombre de ruta físico real. Esta traducción puede ser configurada más tarde. Por lo tanto, sería posible mover un Lisp a una máquina diferente con diferentes nombres de ruta, configurar el nombre de ruta lógica HTTP y, a continuación, el Lisp aún encuentra todo el código fuente, aunque esté en una máquina diferente con una estructura de sistema de archivos diferente. Entonces, para que funcione puede necesitar alguna configuración. Pero es una característica muy útil y es ampliamente utilizada.

Cómo funciona la grabación del código fuente y cómo funciona la grabación de las ubicaciones de origen depende de la implementación y es una característica del respectivo Lisp en combinación con su entorno de desarrollo. Mejor Las implementaciones de Lisp tienen muchas funciones en esta área.

5

También puede utilizar símbolos o do-do-external-símbolos, si lo prefiere:

ejemplo:

>> (do-external-symbols (s (find-package :foo-package)) (print s)) 

FOO-PACKAGE:XXX 
FOO-PACKAGE:YYY 
FOO-PACKAGE:ZZZ 
NIL 

donde XXX, YYY ZZZ & son todos los símbolos externos en el paquete: foo- paquete.