tutorial compiler common include lisp common-lisp clisp

include - compiler - #ifndef en Common Lisp



clisp windows (2)

La pregunta que hiciste

El análogo directo de las condiciones del preprocesador como #if en C es la facilidad de condicionalización #+ tiempo de lectura.

La pregunta que querías preguntar

Para evitar la carga múltiple de un archivo, puede usar el recurso estándar / obsoleto de provide / require , o un sistema complementario como ASDF .

En C, para asegurarnos de no volver a incluir los encabezados incluidos, utilizamos la siguiente estructura:

#ifndef UTILS #define UTILS #include "my_utils.h" #endif

Rompí mi programa Lisp en archivos separados; varios archivos a veces usan el mismo archivo (p. ej., my_utilities es utilizado por varios archivos). Cuando ejecuto el programa, recibo advertencias de que estoy redefiniendo cosas (llamando a la load del mismo archivo varias veces).

Esto se solucionaría haciendo algo similar a #ifndef en C. ¿Cuál es el método Common Blip equivalente o estándar para hacer esto?

Soy bastante nuevo para Lisp. Avíseme si hay mejores prácticas (tal vez, un método diferente de estructurar mis programas) que me falta.


  1. Para las aplicaciones y bibliotecas Common Lisp, se prefiere usar una herramienta de administración del sistema . Como ASDF o lo que sea que su implementación pueda proporcionar. Un sistema es una colección de archivos con dependencias y varias acciones (cargar, compilar, ...).

  2. Siempre puedes verificar el estado del tiempo de ejecución y hacer algo.

Ejemplo:

(unless (fboundp ''foobar) (require "foo") (load "bar")) (unless (find-package ''foobar) (require "foo") (load "bar"))

  1. PROVIDE y REQUIRE son funciones integradas para eso exactamente. Si necesita un módulo , se cargará, a menos que ya se haya provided . Desafortunadamente, esta funcionalidad no está especificada en el estándar, pero las implementaciones pueden proporcionar una funcionalidad útil.

  2. Los tiempos de ejecución de Common Lisp tienen una lista de características en la lista *features* . Puede usar eso para publicitar y verificar la funcionalidad.

Ejemplo:

En tu biblioteca:

(push :cool-new-graphics-library cl:*features*)

En tu código de aplicación:

(when (member :cool-new-graphics-library cl:*features*) (funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL") :death-star))

Common Lisp proporciona una forma de condicionalizar ese tiempo de lectura . El siguiente código solo se leerá cuando esté presente la función :cool-new-graphics-library , y solo así se ejecutará más adelante:

#+cool-new-graphics-library(cngl:draw-space-ship :death-star)

Common Lisp también te permite expresar algo de lógica:

#+(and lispworks cool-new-graphics-library) (cngl:draw-space-ship :enterprise) #-cool-new-graphics-library(warn "no cool graphics library available")

Tenga en cuenta que puede forzar a Lisp a ejecutar código en tiempo de compilación:

(eval-when (:load-toplevel :compile-toplevel :execute) #+(and lispworks cool-new-graphics-library) (cngl:draw-space-ship :enterprise) #-cool-new-graphics-library(warn "no cool graphics library available") )

Para que esto funcione, EVAL-WHEN tiene que estar en el topevel ​​de un archivo. Eso significa que no funcionará en profundidad en formas anidadas. Sin embargo, funciona dentro de un nivel PROGN , LOCALLY , MACROLET y SYMBOL-MACROLET .

Por lo tanto, EVAL-WHEN permite ejecutar código que es parte del archivo que se compila actualmente. Este código puede buscar sistemas cargados, módulos proporcionados, funciones disponibles y más.