sábado, 20 de diciembre de 2008

Scripting en lisp

Hola:

Quería escribir esta entrada para comentar algo que me ha sucedido recientemente y que viene al caso de la utilidad de lisp para escribir scripts para la administración de sistemas, al estilo de lo que se suele hacer en perl.

Veamos la situación: recientemente me compré un Acer Aspire One ZG5 con Linux Linpus preinstalado. Por circunstancias que no vienen al caso tuve que cambiar el sistema operativo para poner Debian el Pc. Pues bien, el problema fue que quise instalar un entorno gráfico ligero ( WindowMaker ) en el cuál pretendía usar wicd para configurar mi red inalámbrica. Para mi sorpresa, wicd no funcionó. Lejos de suponer un problema, configuré la red editando manualmente el archivo /etc/network/interfaces y obtuve conexión a internet. Esto sucedió en el trabajo.

Al llegar a mi casa, más de lo mismo. Wicd no conectaba a mi red wireless y tuve que crear un nuevo archivo de configuración para mi red casera. Resumiendo: la situación era la siguiente: 2 archivos de configuración (/etc/network/interfaces.wep y /etc/network/interfaces.wpa ) y un enlace simbólico al archivo correcto que debía crear manualmente cada vez que quería cambiar de red, además de llamar al dichoso /etc/init.d/networking restart cada vez, para conectar.

Aunque no es algo excesivamente tedioso, enseguida pensé en escribir un script que automatizara el proceso de conectar a la red que quisiera, y se me ocurrió escribirlo en lisp en lugar de hacer el típico shell script. La idea era crear un pequeño programa que borrara el enlace existente, substituyéndolo por un nuevo enlace al archivo de configuración correcto y luego llamara a /etc/init.d/networking restart para conectarme a la red. No parecía difícil hacerlo en lisp, pues.

Para ejecutar procesos del linux desde lisp necesitamos la función (escribí esto para sbcl, no debería ser difícil reescribirlo para cualquier otro lisp) (sb-ext:run-program programa lista_de_argumentos ) . Si queremos llamar a la función sin argumentos, simplemente usaremos como segundo parámetro la lista vacía (nil).

Ahora nuestro programa debería ser como sigue:

Función activar_conexion
Parámetros: nombre de la conexion a activar

Ejecuta rm -f /etc/network/interfaces
Ejecuta ln -s /etc/network/nombre_archivo_configuracion /etc/network/interfaces
Ejecuta /etc/init.d/networking restart

El resto del programa debía consistir en algo de código para guardar los nombres de los archivos de configuración. Ahí se me ocurrió la idea de hacer un programa gráfico que usara ltk. Me mostraría todos los archivos de configuración de que dispongo y yo sólo tendría que clickear en un botón para activar la conexión a internet.

Finalmente, decidí que mantendría una tabla hash llamada *conexiones* con entradas del tipo ( nombre fichero_configuracion ) dónde guardaría las conexiones de que dispongo, y que el procedimiento anadir-conexion me serviría para añadir entradas a la hash. Una vez hecho click en el botón correspondiente la función activar-conexion me activaría la conexión a internet haciendo lo que hemos dicho antes.

Pues bien, aquí tenéis el código fuente:

(require :ltk )
(use-package :ltk )

(defvar *directorio-base* "/etc/network/" )
(defvar *nombre-link* "/etc/network/interfaces" )
(defvar *conexiones* (make-hash-table :test 'equal ))

(defun anadir-nueva-conexion ( nombre nombre_arxivo )
(setf (gethash nombre *conexiones* ) nom_arxivo )
)

(defun activar-conexion ( nombre )
(if (gethash nombre *conexiones* )
(progn
(let
(
(nombre_arxivo (concatenate 'string *directorio-base* (gethash nombre *conexiones* )))
)
(print nombre_arxivo )
(sb-ext:run-program "/bin/rm" (list "-f" *nombre-link* ))
(sb-ext:run-program "/bin/ln" (list "-s" nombre_arxivo *nombre-link* ))
(sb-ext:run-program "/etc/init.d/networking" (list "restart" ))
)
)
)
)

(anadir-nueva-conexion "Eduroam UV" "interfaces.wpa" )
(anadir-nueva-conexion "Red casa" "interfaces.wep" )

(defun main ()
(setq *wish-args* (list "-name" "NetworkSwitcher" ))
(with-ltk ()
(let*
(
(marco (make-instance 'frame :master nil ))
etiqueta
)
(maphash (lambda (key value )
(declare (ignore value ))
(setq etiqueta (make-instance 'button :master marc :width 12 :text key
:command (lambda ()
(print key )
(activar-conexion key ))
))
(pack etiqueta )
)
*conexiones* )
(pack marco )
)
)
)


(main)

Al arrancar el programa se ven 2 botones, uno con la etiqueta "Red casa" y otro con la etiqueta "Eduroam UV". Al hacerles click activo la red correspondiente.

Sencillo, no? Mucha gente pensará que debería leerme la faq de wicd en lugar de perder el tiempo en estas cosas, pero realmente he aprendido y disfrutado haciéndolo, así que me doy por satisfecho.

Adiós!!! Felices fiestas a todos!!

jueves, 27 de noviembre de 2008

Primeros pasos con LTK (parte 3)

A vueltas con el pack

Hoy vamos aprender a colocar nuestros widgets en la pantalla. Quizás no sea un tema muy atractivo, pero sí es absolutamente necesario, así que pongámonos manos a la obra.

Vamos a empezar por crear unas cuantas etiquetas que iremos posicionando de distintas maneras.

(let
(
(marco (make-instance 'frame :master nil ))
(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1"))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))
)
)


El código de arriba nos crea las etiquetas pero no se ocupa de posicionarlas en la pantalla. Es ahora cuando entra en juego el pack. Empecemos por ver cómo las posiciona por defecto:

(with-ltk ()
(let*

(
(marco (make-instance 'frame :master nil ))

(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1"))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))

)
(pack marco)
(pack etiqueta1 )
(pack etiqueta2 )
(pack etiqueta3 )
(pack etiqueta4 )
)
)

Por defecto, pack coloca los widgets de arriba a abajo. El resultado del código anterior es lo siguiente:


Es importante darse cuenta de que LTK no muestra los widgets en el orden en que fueron creados, sino en el orden en que se llama a pack. En el ejemplo anterior, ha puesto arriba a etiqueta1 porque ha sido la primera con la que hemos llamado a pack, pero podríamos hacerlo de cualquier otra manera:





(let*
(
(marco (make-instance 'frame :master nil ))
(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1"))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))
)
(pack marco)
(pack etiqueta4 )
(pack etiqueta2 )
(pack etiqueta1 )
(pack etiqueta3 )
)
y el resultado sería que los widgets se muestran en otro orden, que no tiene nada que ver con el orden en el que fueron creados:


Ahora vamos a situar los widgets lateralmente. Para ello sólo debemos hacer uso de la opción :side del pack. Veamos un ejemplo:

(with-ltk ()
(let*
(
(marco (make-instance 'frame :master nil ))
(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1"))

(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))
)

(pack marco)
(pack etiqueta1 :side :left)
(pack etiqueta2 :side :left)
(pack etiqueta3 :side :left)
(pack etiqueta4 :side :left)
)
)

El resultado es que los widgets se situan de izquierda a derecha:

También podemos situarlos de derecha a izquierda usando :side :right:

(with-ltk ()
(let*

(
(marco (make-instance 'frame :master nil ))
(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1"))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))
)
(pack marco)
(pack etiqueta1 :side :right)
(pack etiqueta2 :side :right)
(pack etiqueta3 :side :right)
(pack etiqueta4 :side :right)
)
)

Fijáos cómo la etiqueta1 ahora está a la derecha:


Por último, veremos cómo poner las etiquetas de abajo a arriba. Esto no suele ser muy útil porque es lo mismo que ponerlas de arriba a abajo llamando a pack en orden inverso, pero lo pongo por completitud. Se hace justo como suponéis, usando :side :bottom:
(with-ltk ()
(let*

(

(marco (make-instance 'frame :master nil ))
(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1"))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))
)
(pack marco)
(pack etiqueta1 :side :bottom)
(pack etiqueta2 :side :bottom)
(pack etiqueta3 :side :bottom)
(pack etiqueta4 :side :bottom)
)
)
Esto es todo lo que veremos hoy sobre pack. Con lo que ya sabéis podéis crear interfaces complicadas. ¿Cómo? Solamente habéis de crear marcos y meter los widgets en ellos en el orden adecuado. En el capítulo sobre el widget frame veremos como hacer esto.

El grid

Aunque en principio no pensaba tratarlo, voy a hablar un poco sobre grid. Es un geometry manager distinto a pack. No deben mezclarse pack y grid en el mismo marco porque podemos crear un pequeño desastre con la colocación de los widgets. De todas formas, grid es útil porque lo que hace es situar los widgets en una cuadrícula, de forma que nos simplifica la vida en aplicaciones tipo hojas de cálculo y similares. Su sintaxis básica es muy sencilla:

(grid widget fila columna)

Fila y columna son enteros, representan el número de fila y columna (lógico). La primera fila es la 0, al igual que la primera columna. Veamos cómo situar nuestras 4 etiquetas en una rejilla 2x2:

(with-ltk ()
(let*

(
(marco (make-instance 'frame :master nil ))
(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1" ))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" ))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" ))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" ))
)
(pack marco)
(grid etiqueta1 0 0)
(grid etiqueta2 0 1)

(grid etiqueta3 1 0)
(grid etiqueta4 1 1)
)
)

El resultado es el esperado:



Para finalizar os voy a enseñar un pequeño truco. Si os fijáis en el ejemplo anterior, no se distinguen unas etiquetas de las otras. Eso es porque no tienen relieve. Pues bien, vamos a añadirlo! Todo widget tiene una opción llamada :relief que puede tomar varios valores. Os pongo un código de ejemplo y tratad de averiguar que hace:
(with-ltk ()
(let*
(
(marco (make-instance 'frame :master nil ))

(etiqueta1 (make-instance 'label :master marco :text "Etiqueta 1" :relief :sunken))
(etiqueta2 (make-instance 'label :master marco :text "Etiqueta 2" :relief :sunken))
(etiqueta3 (make-instance 'label :master marco :text "Etiqueta 3" :relief :sunken))
(etiqueta4 (make-instance 'label :master marco :text "Etiqueta 4" :relief :sunken))
)
(pack marco)
(grid etiqueta1 0 0)
(grid etiqueta2 0 1)
(grid etiqueta3 1 0)
(grid etiqueta4 1 1)
)
)

Hemos hundido las etiquetas, de forma que la separación entre ellas queda visible. Se pueden hacer cosas más bonitas :-)

Nos vemos en el próximo post!

miércoles, 5 de noviembre de 2008

Primeros pasos con LTK (parte 2)

Hola!

Hoy vamos a seguir con la introducción a LTK que iniciamos hace unos días.

Empezaremos por comentar el ejemplo que ya vimos y que nos mostraba "Hola, mundo" en una etiqueta:

(use-package :ltk )
(with-ltk ()
(let
(
( etiqueta (make-instance 'label :master nil :text "Hola, mundo" ))
)
(pack etiqueta)
)
)

Bien. La primera línea es conocida: (use-package :ltk) simplemente importa los símbolos que necesitamos, para no tener que escribir todo el rato ltk:laFuncionQueNosInteresa.

Es en la segunda línea donde empezamos a usar ltk. La macro with-ltk inicializa la librería y ejecuta todo el código que metemos en su cuerpo. Tiene unos parámetros opcionales ( en nuestro caso, la lista vacía --()-- ) que nos permiten controlar ciertas opciones de debug.

Cada tipo de widget en ltk se representa mediante una clase. Por eso, cuando llamamos a make-instance 'label estamos creando una etiqueta. Todos los widgets de ltk tienen unas opciones de inicialización comunes:
  • master : el widget padre. Si lo dejamos a nil, ltk tomará a este widget como del nivel padre
Pack es lo que se llama un "package manager", o gestor de empaquetado. Es la función que usamos cuando queremos situar un widget sobre la pantalla, y se encarga de tareas como su posición relativa a otros widgets y (en ocasiones) su tamaño. Existen varios package managers, pero pack es el más utilizado, así que será el que comentaremos aquí. Si queréis saber más sobre el resto de managers, una forma fácil de empezar es man grid o man place.

Cuando trabajamos con pack lo que hacemos es situar los widgets en cajas. Podemos elegir si situaremos estas cajas de arriba a abajo ( por defecto en pack ), de abajo a arriba, de izquierda a derecha o de derecha a izquierda. También nos permite elegir si queremos que el widget se vea elevado sobre la caja, hundido o de diversas formas.

El widget label ( la etiqueta )

El widget label es uno de los más básicos y sencillos de utilizar. Simplemente es una etiqueta donde podemos mostrar texto.

La forma más común de crear un label es mediante

(make-instance 'label :master suPadre :text "SuTexto" )

Esto ajustará automáticamente el tamaño de la etiqueta al del texto que contiene.

A veces resulta muy conveniente, a fin de realizar interfaces más bonitas, controlar el ancho de las etiquetas para que todas tengan el mismo tamaño. Esto se hace mediante la opción de inicialización :width suAncho , dónde suAncho es un entero. El ancho de un label se mide en carácteres, por tanto :width 10 significará que queremos una etiqueta con un ancho de 10 carácteres.

Evidentemente, hay muchas más opciones interesantes para los label. man label para verlas.

El widget button ( el botón )

El widget button ofrece lo que promete: un botón. Su inicialización es muy similar a la del widget label, excepto por el hecho de que nos deja proporcionarle un argumento command que es la función que ejecutará cuando sea pulsado.

(make-instance 'button :master nil :text "Pulsame"
:command ( lambda ()
(format t "Has pulsado el boton~%" )
)

A ver si imagináis que hace el código anterior.

miércoles, 15 de octubre de 2008

Dibujando gráficas en 2 patadas con CGN

Hola:

Sí, el título podía ser más formal, pero hoy nos interesa ir deprisa...

Vamos a aprender a dibujar gráficas en Gnuplot desde lisp. Gnuplot es un conocido programa para dibujar gráficas de funciones y puntos (las últimas versiones hacen más cosas, como por ejemplo histogramas) que seguramente ya conoceréis. Así que manos a la obra!

Existen muchas alternativas en lo que a controlar gnuplot desde lisp se refiere. En cliki podéis encontrarlas. Aquí me limitaré a enseñaros a dibujar con CGN. ¿ Por qué CGN? Pues porque soy su autor, así que es la librería que mejor conozco y la que suelo usar, aunque no la mejor. Os invito a que probéis el resto y me contéis cómo ha sido la experiencia. Podemos publicarlo en este blog para ayudar a más gente.

¿Cómo instalaremos CGN? Pues de la manera que os imagináis: 

(asdf-install:install 'cgn )

CGN depende de la librería gráfica LTK, así que asdf-install la instalará por vosotros. Ahora bien, para este tutorial os recomiendo usar la versión que se halla en el repositorio darcs,  que se debe instalar a mano. La función plot2d que usaremos aquí sólo se encuentra en esa versión. Lo siento, todavía no he lanzado una release actualizada.

Dibujando con plot2d:

Para empezar a dibujar con CGN sólo hay que saber usar 2 cosas: la macro with-gnuplot y la función plot2d. 

Empecemos por la macro: para dibujar con CGN hay que escribir el código dentro de la macro 

(with-gnuplot () 

;;Código aquí

)

No nos interesa ahora lo que podemos ponerle como argumento. ¡Queremos empezar a dibujar, ya! Pues bien: aquí está lo más sencillo y útil que le podemos poner como argumento: plot2d.

Plot2d es una función que pretende ofrecer la funcionalidad que proporciona el comando del mismo nombre en Maxima.  Su sintaxis básica es :

(plot2d quePlotear rangoX &rest opciones )

rangoX ha de ser una lista con el formato ( 'x xminimo xmaximo ). quePlotear puede ser muchas cosas: un string ( "sin(x)" ) , una función ( #'cos ) , una lambda function, una lista de puntos o una lista conteniendo todo lo anterior. De las opciones no hablaremos de momento, hay prisa!

Por ejemplo, mostramos el seno:

(with-gnuplot () 
  (cgn::plot2d "sin(x)" '(x 0 10 ) ) )















Si le pasamos una función, CGN la dibujará en los puntos que crea necesario:

(with-gnuplot ()
  (cgn::plot2d #'cos '(x 0 10 ) ) )
















Otra opción es hacer un gráfico de puntos:

(with-gnuplot ()
  (cgn::plot2d '(discrete (1 2 3 4 5 6 7 8 9 10 ) (1.1 2.5 4.21 2.12 3.15 4.57 6.87 8.74 12.5 13.4789 ) ) '(x 0 10 ) ) 
)

















Podéis ver una muestra de lo que plot2d puede hacer ejecutando (cgn::plot2d-test). En el manual en pdf que se incluye en la versión de desarrollo se explica todo.

La forma rápida y simple

Existe una forma para que hasta un niño pueda hacer gráficas en CGN. Consiste en usar  el easy-plotter. Easy-plotter es una interfaz gráfica escrita en ltk para la macro plot (sí, esto también es una novedad de la versión del repositorio) que nos permite escribir simplemente la función que usaremos y plotearla. Lamentablemente, no sirve para plotear funciones de lisp ni lambda functions, pero es muy sencilla de usar:

(cgn::easy-plotter)



Parece sencillo, ¿verdad? Probadlo. CGN puede hacer muchas más cosas, pero me tengo que ir a clase, así que no hay tiempo para contarlas. Espero que esto os haya resultado útil. Ah! Por favor, la versión del repositorio está todavía en desarrollo, así que no seáis muy crueles con los fallos que encontréis. ¡Adiós!

sábado, 4 de octubre de 2008

Bienvenidos, sobrelisp!

Desde aquí quiero dar la bienvenida a un blog hermano que ha sido creado recientemente , sobrelisp.blogspot.com.

David y yo esperamos que estos dos blogs se complementen para impulsar lisp en la comunidad hispanohablante.

Buena suerte!

jueves, 18 de septiembre de 2008

Cómo crear un entorno amigable para Lisp en Windows

¿Qué hay de nuevo?

Hoy hablaremos de Lisp y Windows. No es este el mejor sistema operativo para usar Lisp. Tradicionalmente ha habido implementaciones de Lisp para Mac y Unix, aunque algunas compañías como Franz ofrecen buenos compiladores de Lisp para Windows. Esta es una buenísima opción para todos aquellos que no tengan reparos en usar software propietario, puesto que la versión de evaluación de Allegro impone muy pocas limitaciones a los desarrolladores, junto con un gran IDE y un compilador rápido. Sin embargo, hoy hablaremos sobre cómo usar un Lisp libre como es clisp sobre Windows sin dejarnos los nervios en el intento.

El entorno que instalaremos constará de clisp como intérprete de Lisp y emacs + slime como IDE. Muchos de vosotros ya conoceréis emacs, así que no hace falta presentarlo. Slime es un modo de interacción con emacs que permite ejecutar lisp desde un buffer de emacs y muchas otras cosas, como documentación en línea de funciones, inspector de objectos, compilación de archivos desde emacs y mucho más.

Empezaremos por instalar clisp. En sourceforge podemos encontrar el último instalador para Windows, que mientras escribo este artículo es el clisp-2.46-win32-mingw-big.exe. Para instalarlo seguiremos el procedimiento estándar en Windows ( aceptar, aceptar, aceptar ...). Para finalizar, sólamente nos queda una comprobación: vamos al menú inicio -> ejecutar y escribimos "clisp". Si está correctamente instalado veremos aparecer el REPL de clisp. Si no apareciera, desinstalamos clisp y instalamos una versión distinta. Que aparezca clisp de esta manera quiere decir que se ha instalado correctamente en el PATH. De no ser así, todavía se puede instalar emacs+slime, pero será más complicado, de manera que no voy a explicarlo ahora. Si a alguien le interesa que me lo haga saber en un comentario y se lo explicaré.

A continuación procedemos a instalar emacs. Podemos bajarlo desde aquí. He enlazado a la versión 22.3 porque, además de ser la última y mejor versión de emacs, tiene una bonita interfaz en GTK . Lo que bajaremos es un archivo comprimido en formato zip que habremos de descomprimir. Seguidamente crearemos la carpeta C:\emacs y copiaremos allí todo lo que hemos descomprimido, de manera que nos queden las carpetas C:\emacs\bin, C:\emacs\lisp, etc. Para poder usar emacs sólo nos queda crear un acceso directo en el escritorio al archivo C:\emacs\bin\runemacs.exe.

Para finalizar habremos de instalar slime. Para ello descargamos la última snapshot de la cvs desde aquí. Una vez bajado, lo descomprimimos y copiamos el contenido de la carpeta que aparece a C:\, de manera que nos quede, por ejemplo, C:\slime\README, C:\slime\doc, etc... Una vez hecho esto, sólo queda decirle a emacs dónde encontrará a slime. Para ello, abrimos emacs y seleccionamos las opciones "Active region highlighting" i "Parent match highlighting". Estas opciones nos facilitaran editar código fuente en lisp. Seguidamente, guardamos las opciones haciendo click sobre Options -> save options , y nos fijamos en el nombre de archivo que pone en el minibuffer. Esa es la ruta completa hasta el archivo de configuración de emacs. En mi pc, la ruta es C:\Documents and settings\nombre_usuario\Datos de programa\.emacs. Bien, ahora desde emacs abrimos ese archivo y añadimos las líneas siguientes:

(add-to-list 'load-path "/slime/") ; dónde hemos instalado slime
(setq inferior-lisp-program "clisp") ; nuestro lisp.
(require 'slime)
(slime-setup)

Ya está. Ahora cerramos emacs y lo volvemos a abrir para que cargue los cambios en el fichero de configuración ( seguramente, hay otra manera más elegante de hacer esto, pero no la conozco) y ya podemos empezar a usar slime. Para arrancarlo, simplemente escribid "Alt - x " y cuando el minibuffer os pida que escribáis poned slime. Ahora pulsad enter y slime ya cargará.

Podéis ver el resultado a continuación:





















Eso es todo por hoy. Espero que con esto consigáis tener un entorno lisp decente en el que dar forma a vuestras ideas. Adew!

miércoles, 17 de septiembre de 2008

Primeros pasos con LTK ( parte 1 )

Hoy vamos a hablar de la creación de interfaces gráficas de usuario en Lisp. Hoy en día una buena interfaz es un requisito imprescindible para que un programa tenga éxito fuera del ámbito científico o puramente técnico. Pero además, para que el desarrollo del programa sea asumible por el programador, es preciso que el tiempo invertido en crear esa interfaz no sea excesivo.

La librería por excelencia para crear interfaces gráficas en Lisp es LTK ( http://www.peter-herth.de/ltk/ ). LTK es una creación de Peter Herth. Consiste en una tubería que transforma nuestro código lisp en código tcl que es ejecutado por el programa wish. Si no habéis entendido nada de la parrafada anterior, no os preocupéis. No es necesario entenderla para poder usarla, LTK es tremendamente sencilla de usar.

Primeramente, hay que instalar LTK. Para ello habremos de seguir 2 pasos:
  1. Instalamos el lenguaje de programación tcl/tk. Normalmente cualquier distribución de linux lo llevará instalado por defecto. Si no es así, instaladlo, usado apt-get, synaptic, yast, emerge o cualquier herramienta que use vuestra distribución. No es necesario instalar los paquetes de desarrollo.
  2. Instalamos la librería LTK propiamente dicha. Para ello, si disponemos de asdf-install, sólo tendremos que entrar en lisp y teclear
(asdf-install:install 'ltk )
Sólo tendremos que seguir las instrucciones que asdf-install nos irá dictando y ya tendremos LTK instalada.

Nuestro primer programa

Usar ltk es terriblemente fácil. Como muestra, veamos un primer programa que nos muestre el ya clásico "Hola, mundo" en una ventanita:

(use-package :ltk )
(with-ltk ()
(let
(
( etiqueta (make-instance 'label :master nil :text "Hola, mundo" ))
)
(pack etiqueta)
)

)

Veamos cómo nos ha quedado:

Voilà! Aquí tenéis una pequeña screenshoot de LTK corriendo nuestro ejemplo en un Windows XP.

No voy a extenderme hoy sobre que es lo que hace nuestro código. Habrá tiempo para eso. Sólo espero que lo que habéis visto haya despertado vuestro interés por la programación gráfica en Lisp usando LTK.

Hasta la próxima!

martes, 16 de septiembre de 2008

El inicio

Hola a todos desde lispinspain.blogspot.com!

A partir de ahora intentaremos crear un blog dónde congregar a todos los programadores de lisp de habla hispana que, hasta el momento, no disponían de recursos en su idioma.

Siempre se ha dicho que no existe una comunidad alrededor de lisp. Esto es cierto, pero no nos impide que creemos una. La falta de información en su idioma puede hacer que cualquier persona interesada en lisp se desanime a las primeras de cambio, cosa muy triste porque lisp es uno de los lenguajes de programación más antiguos que existen y a la vez uno de los más potentes.

Bueno, chicos y chic@s. Espero que desde esta página se pueda animar a mucha gente a mirar a lisp con un poco menos de miedo.

Nos vemos!