Sep 09

Scheme, CL y Elisp

Tag: admin @ 5:03 am

Al final me he adentrado a estudiar scheme, el dialecto de Lisp mas minimalista de todos, sin embargo a nivel de concepto sea probablemente el mas complejo. El estandar de scheme R5RS cuenta tan solo con 50 paginas, aunque no es el ultimo (R6RS) que ha sido extendido para ser mas practico y aplicable a ciertos proyectos, aunque todas estas extensiones incluidas en el R6RS han sido incluidas a modo biblioteca. Asi que nos disponemos a analizar el R5RS.

Sin embargo, antes de que os adentreis en uno de estos 3 dialectos, deberiais hacer un test de personalidad, yo ya lo hice, al leer el libro “The land of lisp”. Ahora es vuestro turno:

Selection_022

Y bien? ya habeis elegido? Si habeis elegido la opcion A, parece que os gusta el poder duro y crudo en vuestro lenguaje. No os importa si vuestro lenguaje a un poco sucio debido por la cantidad de compromisos pragmaticos, siempre que podais escribir codigo que se ajuste a vuestras necesidades. En ese caso, Common Lisp (CL) es vuestro lenguaje, dando una increible funcionalidad.

Si habeis elegido la opcion B, eso es porque te gustan los lenguajes limpios y elegantes. Estais mas interesados en problemas de programacion fundamental y sois felices siempre y cuando exista un camino bonito para realizarlo, contemplando el codigo precioso en vuestro codigo, ocasionalmente escribiendo un research paper de problemas sobre computacion teorica. Es por eso que scheme es vuestro lenguaje, creado por Guy L. Steele y Gerald Jay Sussman envolviendo la busqueda sobre el lisp ideal. Programar en scheme tiende a ser ligeramente mas detallado, debido a que los schemers tienden a pensar mas en la pureza matematica de su codigo que en crear los programas lo mas corto posible.

Sin embargo, si habeis elegido la opcion C, es porque sois gente que quereis un todo en uno; el poder de CL al mismo tiempo que quereis la pureza matematica de scheme. En este momento, no existe un dialecto lisp que completamente llene vuestras necesidades, pero sin duda esto cambiara en un futuro. Un lenguaje sin embargo que servira para vosotros es Haskell. Haskell obviamente no es considerado un dialecto Lisp, pero sigue la gran mayoria de los paradigmas populares entre lisperos como la sintaxis uniforme, soporte para listas de forma nativa y confiando fuertemente en funciones de order alto. Tiene un importante rigor matematico (incluso mas que scheme), lo que permite esconder la funcionalidad mas potente bajo una superficien chirriantemente limpia. Esto es esencialmente un lobo con la vestimenta de una oveja. Como Lisp, Haskell es un lenguaje que todo programador encontrara un beneficio una vez haya investigado lo suficiente.

A mi me salio la C, simplemente porque estoy como una cabra, pero me hubiese llevado las 3 mascotas a casa. Asi que yo soy de los que quiero scheme, CL y Haskell. Hay que tener mucho cuidado al aprender uno de estos lenguajes, ya que generalmente los manuales, tutoriales y otros libros tienden a ser bastante malos, con ejemplos que se centran y se focalizan en IA y se cargan toda la esencia del lenguaje. Asi que me he dedicado a ver cada uno de estos libros y decidir, basado en opiniones de otros, analisis, y demas, cuales son los mejores libros para aprender cada uno de estos lenguajes a nivel desde el principio y mas claramente sin mezclar conceptos.

  • Para aprender Scheme: The little schemer
  • Para aprender Elisp: C-h i en emacs tiene un estupendo manual de elisp en el que practicar en el propio entorno.
  • Para aprender CL:  Common LISP: A Gentle Introduction to Symbolic Computation
  • Para aprender Haskell: Learn You a Haskell for Great Good!: A Beginner’s Guide
  • El libro mas avanzado de Scheme: Structure and Interpretation of Computer Programs
  • El libro mas avanzado para Elisp: An Introduction to Programming in Emacs Lisp
  • El libro mas avanzado para CL: On Lisp
  • El libro mas avanzado para Haskell: The Haskell Road to Logic, Maths and Programming

Analisis del estandar R5RS

1. Vista General

1.1 Semantica

Los tipos estan asociados con valores (objetos) y no con variables. Todos los objetos son creados en el curso de la computacion de scheme y nunca son destruidos.

Los argumentos en scheme son siempre pasados por valor lo que significa que las expresiones de los argumentos son evaluadas antes que el procedimiento gane el control.

En scheme cada entero (Z) es racional (Q), cada racional es real (R), y cada real es complejo (C).

1.2 Sintaxis

La representacion uniforme es la susceptibilidad de los programas scheme y tratamiento de informacion uniforme por otros programas scheme.

<en desarrollo>

El lenguaje Lisp

1. El lenguaje lisp

Antes de comenzar, debemos realizar algunas aclaraciones, y es que LISP se refiere al lenguaje creado por John McCarthy originalmente (LISP1.5). LISP son las raices del resto de lenguajes derivados, sin embargo hoy en dia no se emplea dicho lenguaje original. Sin embargo, cuando nos referimos a Lisp nos referimos al dialecto CL (Common Lisp). Podemos referirnos al grupo de dialectos como scheme y CL entre otros mediante “lisp-based” o “Lisp family”.

1.1 Propiedades del lenguaje lisp

Lisp es un lenguaje multiparadigma, es prodedural, orientado a objetos, reflectivo y metaprogramado.

El lenguaje lisp esta basado en s-expression (solo la sintaxis, no el lenguaje); es decir, expresions simbolicos, que es una notacion en forma de texto para representar estructuras de datos de arbol, basadas en listas anidadas donde cada sublista es un  subarbol.

En lisp, el primer elemento de cada s-expression es un operador, mientras que el resto de elementos son tratados como datos. Esta forma se denomina notacion prefija o notacion Polaca Cambridge, a diferencia de la notacion infija donde el operador se encuentra dentro.

Lisp tiene precision infinita para enteros (numeros grandes), por lo que las operaciones booleanas a nivel de bit estan exemptas de las limitaciones a nivel de maquina, excepto por la memoria disponible.

En lisp, “todo” son listas.  Hay que matizar que no todo son listas, realmente es una estructura comun que se usa para el codigo, pero cuando se quiere realizar algo eficiente, no se usa listas, sino que se usan vectores, arboles, tablas hash, etc.

En lisp nil es nulo.

En lisp t es verdadero.

En lisp esto seria una lista (list 1 2 3). Aunque realmente la lista, no seria 1 2 3, sino list 1 2 3. Es decir, son 4 elementos si te quieres referir a la lista, y el resultado de ejecutar (evaluar) eso, es una lista 1 2 3.

En lisp tenemos simbolos, no variables (realmente hay que matizar que tambien hay variables. Donde por ejemplo (quote a) a seria un simbolo. Variables y simbolos son cosas diferentes; un simbolo es un identificador unico, mientras que una variable, es algo que contiene un valor. Pero como es util poder llamar a variables unicamente en la sintaxis las listas-como-codigo, se usan simbolos para denotar variables.

Lisp no es case sensitive. Otra aclaracion mas, realmene es case-sensitive, lo que ocurre es que el reader por defecto convierte todo a mayusculas. Pero: 1) se puede apagar y 2) se pueden escapar simbolos asi:

foo == FOO

pero

\foo == fOO

En lisp el primer parametro sera el nombre de una funcion. (funcion param1 param2 paramX) donde se emplea espacio para separar parametros.

Todo en lisp son funciones. Aqui cabe aclarar, que realmente no todo son funciones, sino mas bien que lo que en otros lenguajes son operadores, en Lisp son funciones.

Lisp basicamente tiene 3 operaciones:

  1. Extraer un miembro de una lista.
  2. Anadir/eliminar un miembro de una lista.
  3. Extrae un miembro de una lista de manera no destructiva.

En lisp existen las celdas cons (o expresiones S no atomicas), una celda cons se compone de dos punteros. La operacion car extrae el primer puntero, y la operacion cdr extrae el segundo. Lisp fue implementado en IBM 704 a finales de 1950, en dicho hardware existia soporte especial para dividir una palabra de la maquina de 36 bits en 4 partes, es de aqui de donde viene dicho origen de los nombres. CAR (Contents of the Address part of Register number) y CDR (Contents of the Decrement part of Register number).

 1.2 Lisp basico

Para definir variables globales (tambien llamadas top-level definition, o bien dynamic variable o special variable):

(defparameter *big* 100)

Los asteriscos alrededor de la variable (llamados earmuffs) son completamente opcionales aunque se recomienda usar. Esto devolvera *BIG* debido a que se ha definido una nueva variable. Si queremos ver su valor podemos hacer lo siguiente:

*big*

Podemos definir variables globales de otro modo (con defvar). Sin embargo estas actuaran como constantes, ya que no sobreescribira el valor una vez asignado:

(defvar *small* 2)

Para definir una funcion lo hacemos de la siguiente manera:

(defun factorial (o)

“optional command”

if (= n 1)

1

( * n (factorial (- n 1) ) ) )

Para usar una funcion dentro de un fichero podemos hacer lo siguiente:

(load “file.el”)

(factorial 1)

(factorial 10)

Para anadir trazas a dichas funciones podemos hacer lo siguiente:

(trace factorial)

(factorial 11)

Para listar operaciones, como “todo son listas” (la palabra reservada setf proviene de set field):

(setf a ‘(1 2 3 4) )

Una funcion interesante a utilizar es ash, que permite realizar desplazamientos de bits a la izquierda o derecha sobre un valor, por ejemplo:

(ash 11 1)

(ash 11 -1)

Para definir variables locales en Lisp lo hacemos de la siguiente forma:

(let (declaraciones de variables)

(body) )

Esto nos permite hacer multiples declaraciones, por ejemplo:

(let (a 5)

(b 9)

(+ a b))

Para definir funciones locales en Lisp lo hacemos de la siguiente forma:

(flet ((nombre-de-la-funcion (argumentos)

… body de la funcion…))

…body…)

Por ejemplo:

(flet ((f (n)

(+ n 10)))

(f 5))

De la misma forma podemos declarar multiples funciones al mismo tiempo:

(flet ((f (n)

(+ n 10))

(g (n)

(- n 3)))

(g (f 5)))

Para hacer que los nombres de funciones esten disponibles en las funciones definidas, empleamos el comando labels en lugar de flet:

(labels ((a (n)

(+ n 5))

(b (n)

(+ (a n) 6)))

(b 10))

Mas informacion:

https://en.wikipedia.org/wiki/Lisp_%28programming_language%29

http://en.wikipedia.org/wiki/S-expression

http://en.wikipedia.org/wiki/CAR_and_CDR

<en desarrollo>

 

One Response to “Scheme, CL y Elisp”

  1. GNU/Emacs » Libros Lisp says:

    […] Scheme, CL y Elisp […]

Leave a Reply

You must be logged in to post a comment.