Estructuras de Control en LISP





Las funciones en LISP pueden evaluarse en serie, condicional, iterativa o recursivamente. La recursividad se estudiará más adelante, mientras que la evaluación condicional e iterativa se tratan a continuación.Detrás de la noción de evaluación condicional existe una colección de funciones en LISP, las cuales se clasifican como «predicados». Un predicado es cualquier función que cuando es evaluada devuelve el valor t (significando true) o nil (significando false). En otros lenguajes, estos predicados básicos se definen normalmente vía operadores «relacionales» y «booleanos». A continuación se da una lista de los principales predicados del LISP, junto con sus significados. Aquí e, e1 y e2 son listas, x, x1 y x2 son expresiones aritméticas y p, p1, p2,…, son predicados.

 

PREDICADO   SIGNIFICADO
 

(PLUSP X)

   

Devuelve t si x>0 y ni si no lo es.

 

(MINUSP X)

   

Devuelve t sí x<0 y nil en los demás casos.

 

(ZEROP X)

   

Devuelve t si x=0 y nil en los otros casos.

 

(LESSP x1 x2)

   

Devuelve t si x1<x2 y nil en los demás casos.

 

(GREATERP x1 x2)

   

Devuelve t si x1>x2 y nil en los demás casos.

 

(AND p1 p2 .. pn)

   

Devuelve t si todos los p1, p2, .., pn son t y nil en los otros casos.

 
 

(OR p1 p2 .. pn)

   

Devuelve t si uno o más de los p1, p2, .., pn es t y nil en los demás casos.

 

(NOT p)

   

Devuelve t si p es nil y nil en los demás casos.

 

(FIXP x) – (FLOATP x)

   

Devuelve  t  si  x  es  entero  –  punto  flotante, respectivamente, y nil en los demás casos.

 
 

(EQUAL e1 e2)

   

Devuelve t si el valor de e1 es el mismo que el de e2 y nil en los otros casos.

 

(NUMBERP e)

   

Devuelve t si e es un átomo numérico y nil en los otros casos.

 

(ATOM e)

   

YA VISTA.

 

(NULL e)

   

YA VISTA.

 

Para ilustrar estas funciones, supongamos que la lista PUNTUACIONES tiene el valor (87.5, 89.5. 91.5) y la lista L tiene de nuevo el valor (pascal fortran cobol pli). La mayoría de los ejemplos de la tabla siguiente utilizan estos valores para ilustrar los predicados del LISP.

Algunos  de  estos  ejemplos  ilustran  las  situaciones «límites» que surgen en el procesamiento de listas y la importancia de aplicar funciones a unos argumentos con el tipo correcto. Por ejemplo, los predicados «zerop», «plusp», «minusp», «lessp» y «greaterp» se aplican principalmente a expresiones que tienen valores numéricos.

 

 

PREDICADO                            RESULTADO
 

(PLUSP (CAR SCORES))

   

t

 

(MINUSP 3)

   

Nil

 

(ZEROP(CAR L))

   

Indefinido

 

(LESSP (CAR SCORES) (CADR SCORES))

   

t

 

(GREATERP (CAR SCORES) 90)

   





Nil

(AND (PLUSP(CAR SCORES)) (LESSP(CAR SCORES) 90)    

T

 
 

(EQUAL (CAR L) ‘LISP)

   

Nil

(OR (GREATERP(CAR SCORES)90) (GREATERP(CADR SCORES)90))    

Nil

 
 

(NUMBERP(CAR L))

   

Nil

 

(NOT(NUMBERP(CAR L)))

   

T

Expresiones condicionales

Una expresión condicional en LISP es equivalente a una serie de sentencias if anidadas en lenguajes tipo Pascal. Tiene la siguiente forma general:

 

(cond (p1 e1) (p2 e2)


(pn en))

 

Cada uno de Los p1, …, pn, denota un predicado y cada una de las e1, …, en, la expresión que le corresponde, devolviendo la función como resultado la primera e de la secuencia, para la cual el correspondiente p es verdad y saltándose el resto.(Si ninguno de los p es verdad, la condición cond devuelve nil.)

Por tanto, en efecto, esto es lo mismo que el siguiente código en Pascal:

 

if p1 then e1

else if p2 then e2 else

.

.

.

else if pn then en

 

En el caso de que queramos que la última alternativa en se evalúe en «todos Los demás casos» —es decir, siempre que todos los p sean nil— entonces ponemos pn a t en esta expresión condicional. Por ejemplo, supongamos que queremos calcular el IMPUESTO de una persona como el 25% de sus ingresos BRUTOS siempre que este último exceda de 18.000 dólares y como el 22% de BRUTO en los demás casos. La siguiente expresión condicional realiza esto:

 

(cond ((greaterp BRUTO18000) (setq IMPUESTO (* 0.25BRUTO))) (t (setq IMPUESTO (* 0.22 BRUTO))))

 

Por tanto, esto es equivalente a la siguiente expresión en Pascal:

 

if BRUTO >18000 then IMPUESTO := .25 * BRUTO else IMPUESTO := .22 * BRUTO

 

Surge una confusión cuando alcanzamos el final de una expresión compleja en LISP, que se refiere sobre cuántos paréntesis derechos deben aparecer al final para mantener el equilibrio necesario. Esta es una buena situación para usar el corchete, ], para forzar un cierre múltiple sin tener que contar los paréntesis izquierdos existentes. Por tanto, podemos escribir lo anterior como:

 

(cond ((greaterp BRUTO 18000) (setq IMPUESTO (* 0.25 BRUTO))) (t (setq IMPUESTO (* 0.22 BRUTO]

 

y todos los paréntesis abiertos y no cerrados se cerrarán hasta el comienzo de la expresión condicional.

Aunque la recursividad es la forma primaria de expresar los procesos repetitivos en LISP, en algunas situaciones se prefiere la especificación de bucles «iterativos». Para servir a esta necesidad, LISP contiene la «característica prog», la cual, combinada con la función «go» (sí, ¡es la vieja sentencia goto!) permite que se especifique un tipo primitivo de bucle. Además, algunas implementaciones del LISP contienen otras estructuras de control comparables a las sentencias while o for encontradas en lenguajes como el Pascal .

La «característica prog» también contiene una facilidad para definir «variables locales» dentro de la definición de una función. A menos que se especifique así, todas las variables de un programa en LISP son (por defecto) de ámbito global. La forma general de la característica prog es la siguiente:

 

(prog (locales) e~ e2… en)

 

«Locales» es una lista que identifica a las variables locales de esta función. Cada una de Las e denote un término arbitrario en LISP y puede estar precedido opcionalmente por una «etiqueta». La etiqueta puede ser, a su vez, cualquier símbolo único y sirve para dar un punto de bifurcación a la función «go» que aparece en cualquier lugar entre estas expresiones. La función go tiene la siguiente forma general:

 

(go etiqueta)

 

«Etiqueta» es la etiqueta simbólica que precede a alguna otra expresión dentro de la lista de expresiones. Por ejemplo, si queremos especificar la ejecución repetida de una expresión e 10 veces, controlada por la variable (local) I, podemos escribir el siguiente segmento de programa:

 

(prog (I)

(setq I 1) bucle

(setq I (addl b)

(cond ((lessp I 11) (go bucle))) )

 

Esto es equivalente al siguiente bucle en un lenguaje como el Pascal:

 

I:= 1;

bucle:

I := I + 1;

if I < 11 then goto bucle





También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *