CAPÍTULO IV: Programación Funcional

Documentos relacionados
Tema 3.- Predicados y sentencias condicionales

GUÍA BÁSICA DE SCHEME v.4

Principios de Computadoras II

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Algoritmos. Medios de expresión de un algoritmo. Diagrama de flujo

Elementos de un programa en C

2. EXPRESIONES 3. OPERADORES Y OPERANDOS 4. INDENTIFICADORES COMO LOCALIDADES DE MEMORIA

Lenguajes de Inteligencia Artificial Segundo curso. Primer cuatrimestre

Manual de referencia de Scheme 1. El lenguaje de programación Scheme

2.2 Nombres, Ligado y Ámbito

Algoritmos y programas. Algoritmos y Estructuras de Datos I

Programación n Orientada a Objetos Sentencias Java Parte I. Ing. Julio Ernesto Carreño o Vargas MsC.

Todo programa en 'C' consta de una o más funciones, una de las cuales se llama main.

El lenguaje C. 1. Identificadores, constantes y variables

Programación Orientada a Objetos Sentencias Java Parte I Ing. Julio Ernesto Carreño Vargas MsC.

PHP: Lenguaje de programación

$0 Representa al parámetro cero o nombre del programa $1 Representa al parámetro uno $2 Representa al parámetro dos

Programación en java. Estructuras algorítmicas

Lección 2 Introducción al lenguaje C

Ficha de Aprendizaje N 13

Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

Valores Booleanos Interpretación #t Cierto #f Falso

Manual de turbo pascal

4. Operadores Operador asignación

INTRODUCCIÓN A LA PROGRAMACIÓN EN FORTRAN. Métodos Numéricos Carlos Zotelo

INTRODUCCIóN A LA PROGRAMACIóN APUNTES DE JAVA APUNTES DE JAVA

FUNDAMENTOS DE INFORMÁTICA

Manual de Lisp para IACS (Curso 91 92)

SISTEMAS INFORMÁTICOS PROGRAMACION I - Contenidos Analíticos Ing. Alejandro Guzmán M. TEMA 2. Diseño de Algoritmos

Tema 4. Operadores y Expresiones

Programación en C. Algoritmo y Estructura de Datos. Ing. M. Laura López. Programación en C

Carlos Montenegro. Programación Orientada a Objetos Proyecto Curricular de Ingeniería de Sistemas

Estructuras de Control. Secuencia y Selección

Programación de Computadores 4 Iteraciones y Decisiones. Prof. Javier Cañas. Universidad Técnica Federico Santa María Departamento de Informática

Distinguir las diferentes estructuras de repetición utilizadas en problemas con bucles: mientras, repetir mientras, para.

REFERENCIA DEL LENGUAJE

Operadores y Expresiones

Guía práctica de estudio 05: Diagramas de flujo

Estructuras de control

Lenguaje de programación C. Introducción

Tema 3. Tipos de datos simples

TECNICO SUPERIOR EN INFORMÁTICA EMPRESARIAL MÓDULO INTRUCCIONAL

Desde los programas más simples escritos en un lenguaje de programación suelen realizar tres tareas en forma secuencial.

Programcaión Básica. Secuencias de Control y Repetición. Arturo Vega González.

funciones printf scanf

Programación. Test Autoevaluación Tema 3

Constante: Una constante es un dato numérico o alfanumérico que no cambia durante la ejecución del programa.

5. Sentencias selectivas o condicionales

Centro Asociado Palma de Mallorca. Antonio Rivero Cuesta

Un identificador le da nombre único a un elemento en un programa (Variables, procedimientos, etc.). No puede contener operadores como + - * /

Curso de Programación Avanzada en C

Estatutos de Control C# Estatutos de Decisión (Selección)

Exterior del algoritmo. Entorno. Usuario. Procesador. Escribir. v1 v2 v3. Leer. <acción> {; <acción>}

Datos y tipos de datos

PROCESADORES DE LENGUAJE. Hoja de ejercicios de FLEX

Tema 3: Tipos y clases

DIAGRAMAS DE FLUJO ELEMENTOS E INSTRUCCIONES A USAR EN UN DIAGRAMA DE FLUJO

Java Avanzado. Guía 1. Java Avanzado Facultad de Ingeniería. Escuela de computación.

Tema 2. El lenguaje JAVA

SENA Distrito Capital Centro de Electricidad, Electrónica y Telecomunicaciones ADSI - Ing. Espec. Javier Vaquiro

Caracteres y Cadenas Conversión de Datos Funciones y procedimientos Archivos cabecera. Fundamentos de programación

DESCRIPCIÓN ESPECÍFICA NÚCLEO: COMERCIO Y SERVICIOS SUBSECTOR: INFORMÁTICA

Tema 3: Tipos y clases

Expresiones y sentencias

Proyecto de Innovación Docente: Guía multimedia para la elaboración de un modelo econométrico.

Enteros. Son los números que no contienen componentes fraccionarios y, por tanto, no contienen punto decimal.

Semántica Denotacional

Fundamentos de programación

LENGUAJE. Tema 2 Elementos de un programa

Computación II. Introducción a Visual Basic

Es toda la información que utiliza el computador. Según sea la información que guardemos en los datos, se clasifican en los siguientes tipos:

Funciones Tipos de funciones y Recursividad

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

En este artículo vamos a conocer los tipos de datos que podemos manejar programando en C.

Fundamentos de Programación Visual Basic

Programación en Pascal

Estructuras de Control

5.3 Tipos de Datos en Prolog

Álgebra y Trigonometría Clase 2 Ecuaciones, desigualdades y Funciones

Fundamentos de Programación 2017-I

Tema 7. Generación de código

TEMA 4. ESTRUCTURAS DE CONTROL

FUNDAMENTOS DE INFORMÁTICA

Ejercicio 3 Funciones Parte 1.

Unidad II. Fundamentos de programación en Java. Ing. José Luis Llamas Cárdenas

Herramientas de Programación. M.C. Juan Carlos Olivares Rojas

Principios de Computadoras II

Estructuras en LabVIEW.

Herramientas computacionales para la matemática MATLAB:Introducción

Estructuras de Datos. La pila es un objeto dinámico en constante cambio.

7.4. UTILIDADES DE LAS PILAS

No todos los LRs finitos se representan mejor con ERs. Observe el siguiente ejemplo:

Constantes. Las constantes no cambian durante la ejecucion de un programa en C++, en C++ existen 4 tipos de constantes:

Sistemas Operativos sesión 13: shell-scripting

EJERCICIOS DE LENGUAJES Y PARADIGMAS DE PROGRAMACIÓN (CUESTIONES DE EXAMEN) PROGRAMACIÓN FUNCIONAL

LEX. Las definiciones y subrutinas son opcionales. El segundo %% es opcional pero el primer %% indica el comienzo de las reglas.

Inicio del programa. Entrada de datos. Proceso de datos. Salida de datos. Fin del programa

Transcripción:

CAPÍTULO IV: Programación Funcional Prof. Teddy Alfaro 4.1 Introducción a la Programación Funcional 1

Programación Funcional Paradigma diferente a los imperativos, que se aleja de la máquina de von Neumann Basado en funciones matemática (notación funcional lambda de Church No existen realmente arquitecturas de computadores que permitan la eficiente ejecución de programas funcionales LISP es el primero, del cual derivan Scheme, Common LISP, ML y Haskell Funciones Matemáticas Un función es una proyección de un conjunto dominio a uno que es el rango f: D R La evaluación de funciones está controlada por recursión y condiciones (imperativos lo hacen normalmente por secuencias e iteraciones Funciones matemáticas entregan siempre el mismo valor para el mismo conjunto de argumentos y, por lo tanto, no tiene efectos laterales. 2

Formas Funcionales (funciones de orden superior Toman funciones como parámetros y/o producen funciones como resultado Composición de Funciones h f g entonces: h(x f(g(x Construcción. Lista se funciones que se aplican [f, g](x produce (f(x, g(x Aplicar a todo. Una función se aplica a lista arg. (f, (x, y, z produce (f(x, f(y, f(z Fundamentos de la PF La PF pura no usa variables ni asignación Repetición debe ser lograda con recursión Un programa consiste de definición de funciones y aplicación de éstas La ejecución del programa no es nada más que la evaluación de funciones La transparencia referencial se refiere a que la evaluación de una función simpre produce el mismo resultado 3

Lenguajes Funcionales El lenguaje provee algunas funciones básicas, que son primitivas para construir funciones más complejas. Se definen algunas estructuras para representar datos en los parámetros y resultados de las funciones. Normalmente se implementan mediante interpretadores, pero también se pueden compilar. 4.2 Introducción al Lenguaje Scheme Sintaxis, listas, operadores básicos, expresiones lambda y definición de variables 4

Origen de Scheme Desarrollado en el MIT a mediados del 70 Es un dialecto de LISP Usado para enseñanza de programación Características: Pequeño con sintaxis y semántica simple Nombres tienen ámbito estático Funciones son entitades de primera clase, y por lo tanto se tratan como cualquier valor Sintaxis Palabras claves Variables Datos constantes (e.g. números; caracteres; strings; vectores, listas y símbolos citados Formas estructuradas Blancos y comentarios (después de ; 5

Identificadores Corresponden a palabras claves, variables y símbolos, que no son sensible a mayúsculas Se forman de: mayúsculas y minúsculas [ A.. Z, a.. z ] Dígitos [ 0.. 9 ] Caracteres [?!. + - * / < = > : $ % ^ & _ ] Identificadores no pueden comenzar con ningún carácter que comienza un número (i.e. dígito, +, - y., excepto casos de identificadores como + y... Ejemplo de Identificadores X3 y?$!!! Abcd y AbcD 8id Son válidos Son el mismo no es válido 6

Constantes Básicas String: se escribe usan citado doble ( e.g. Un string es sensible a Mayusculas Un caracter precede de #\ e.g. #\a Un número pueden ser enteros, fraccionarios, punto flotante y en notación científica e.g. -365, 1/4, 23.46, 1.3e27 Números complejos en coordenadas rectangulares y polares e.g. 2.7-4.5i +3.4@-0.5 Booleanos son los valores #f (falso y #t (verdadero Ambiente Interactivo de Scheme Corresponde al ciclo: leer, evaluar e imprimir (denominado REPL. El sistema entrega un pronto, se ingresa la expresión, el sistema evalúa y entrega el resultado. Ejemplo: Hola Scheme => Hola Scheme (Toda constante evalúa en la misma constante Es posible cargar y salvar en un archivo para facilitar el proceso de desarrollo. 7

Listas Las listas se escriben con paréntesis redondos (a b c d Listas contienen elementos de cualquier tipo, y se pueden anidar (lambda (x (* n n Una función se escribe como una lista en notación prefija, correspondiendo el primer elemento de la lista a la función y los siguientes a los argumentos (+ 3 14 ;=> 17 Funciones Aritméticas Los nombres +, -, * y / son nombres reservados para las operaciones aritméticas. Funciones se escriben como listas en notación prefija: (+ 1/2 1/2 ;=> 1 (- 2 (* 4 1/3 ;=> 2/3 (/ (* 6/7 7/2 (- 4.5 1.5 ;=> 1.0 8

Evaluación de Listas Toda lista es evaluada, salvo que se especifique lo contrario con citación simple (quote (quote (a b c d ;=> (a b c d (a b c d ;=> (a b c d (a b c d ;=> ERROR ( a no es proc. Al no usar quote, Scheme trata de evaluar considerando en el ejemplo a a como variable de función. Operadores Básicos de Listas car devuelve el primer elemento de la lista: (car (a b c d ;=> a cdr devuelve el resto de la lista (sin el primer elemento: (cdr (a b c d ;=> (b c d 9

Estructura de una Lista (A (B C D A B D C Constructores de Listas cons construye una nueva lista cuyo car y cdr son los dos argumentos: (cons a (b c d ;=> (a b c d (cons (car (a b c(cdr (a b c;=> (a b c (cons a b ;=>? list construye una lista con todos los argumentos (list a b c d ;=> (a b c d (list ;=> ( 10

Listas Impropias A B D E C (A (B C D. E (A. ( (B. (C. (. (D. E Variables y Expresiones Let Let permite definir variable que se ligan a un valor en la evaluación de expresiones Sintaxis: (let ((var1 val1 exp1 exp2 Ejemplo: (let ((x 2 (y 3 (* (+ x y (- x y => -5 Variables son sólo visibles dentro del cuerpo de LET! 11

Expresiones Lambda Permite crear un nuevo procedimiento Sintaxis: (lambda (var1 var2 exp1 exp2 Ejemplo: ((lambda (x (* x x 3 ;=> 9 Una expresión lambda es una objeto tipo procedimiento que no tiene nombre! Ejemplo: Expresión Lambda (let ((square (lambda (x (* x x (list (square 2 (square 3 (square 4 ;=> (4 9 16 12

Relación entre Let y Lambda Nótese que: equivale a: (let ((var 1 val 1 (var m val m exp 1 exp n ((lambda (var 1 var m exp1 exp n val 1 val m Especificación de Parámetros Formales Lista propia de parámetros (var 1 var 2... var n ((lambda (x y (list x y 1 2 ;=> (1 2 Parámetros único var r ((lambda x (list x 1 2 ;=> ((1 2 Lista impropia de parámetros (var 1 var 2... var n. var r ((lambda (x. y (list x y 1 2 3 ;=> (1 (2 3 13

Definiciones de Nivel Superior Las variables definidas con let y lambda son sólo visibles en el cuerpo de las expresiones (local. El procedimiento define permite definir variables de nivel superior (global Definiciones de nivel superior permiten visibilidad en cada expresión donde no sean escondidas por otro ligado (e.g. Una variable definida con el mismo nombre mediante let oculta a la de nivel superior Ejemplo de uso de Define (define pi 3.1416 ;=> pi (define square (lambda (x (* x x ;=> square (square 3 ;=> 9 (let ((x 2(square 4 (* x square ;=> 8 14

Abreviación en Definición de Funciones La forma: (define var 0 (lambda (var 1 var n e 1 Se puede abreviar como: (define (var 0 var 1 var n e 1 Ejemplo: equivale a: (define square (lambda (x (* x x (define (square x (* x x Expresiones Condicionales En Scheme también es posible condicionar la realización de determinada tarea Sintaxis: (if test consecuencia alternativa Ejemplo: (define (abs n (if (> n 0 n (- 0 n (abs -27 ;=> 27 15

Predicados Procedimientos para expresiones relacionales =, <, >, <= y >= Procedimientos e.g. (= 3 para 4 expresiones => #f lógicos or, and y not e.g. (and (> 5 2 (< 5 10 => #t Otros Predicados Lista nula: null? (null? ( => #t Argumentos equivalentes: eqv? (eqv? a a => #t Ejemplo: (define (reciproco x (if (and (number? n (not (= n 0 (/ 1 n (error reciproco reciproco: división no válida 16

Expresión Condicional Múltiple Scheme provee expresiones que se evalúan condicionalmente. Sintaxis: (cond (test1 exp1 (test2 exp2 (else exp n El uso de else es opcional, siendo equivalente su uso a colocar #t Ejemplo de Condicional Múltiple (define abs (lambda (x (cond ((= x 0 0 ((< x 0 (- 0 x (else x 17

Un ejemplo más complicado (define nota (lambda (cert lect tar (let ((a ((lambda (c (cond ((< c 45 0 ((> c 60 0.3 (else (/ (* 0.3 (- c 45 15 cert (display "alfa: " (display a (newline (+ (* a tar(* (- 1 a (+(* 0.75 cert (* 0.25 lect (nota 52.5 60 100 alfa:.15 ;=> 61.21875 Algo más sobre Predicados Cualquier objeto se interpreta como #t La lista nula ( equivale a #f Se definen los predicados: pair? : verifica si es un par (lista propia o impropia number? : verifica si es número string? : verifica si es un string 18

4.3 Recursión en Scheme Recursión simple y asignación Recursión Simple Un procedimiento recursivo es aquel se aplica a si mismo. Ejemplo: (define length (lambda (ls (if (null? ls 0 (+ 1 (length (cdr ls ; => length (length '(a b c d ; => 4 19

Ejemplo1: Procedimiento memv ;; El siguiente procedimiento busca x en la lista ls, ;; devuelve el resto de la lista después de x ó ( (define memv (lambda (x ls (cond ((null? ls ( ((eqv? x (car ls (cdr ls (else (memv x (cdr ls ; => memv (memv 'c '(a b c d e ; => (d e Ejemplo2: Procedimiento remv ;; Devuelve la lista equivalente a ls eliminando ;; toda ocurrencia de x (define remv (lambda (x ls (cond ((null? ls ( ((eqv? x (car ls (remv x (cdr ls (else (cons (car ls (remv x (cdr ls ; =>remv (remv 'c '(a b c d e c r e d ;=> (a b d e r e d 20

Ejemplo: Copiar Árbol ;;; tree-copy: copia en forma recursiva el arbol tr (define tree-copy (lambda (tr (if (not(pair? tr tr (cons (tree-copy (car tr (tree-copy (cdr tr ; =>tree-copy (tree-copy '(a (b c d (d (e f(h ; =>(a (b c d (d (e f (h Ejemplo de Recursión (1/3 ;;; abs-all: genera una lista con los valores ;;; absolutos de la lista ls (define abs-all (lambda (ls (if (null? ls ( (cons (abs (car ls (abs-all (cdr ls ; => abs-all (abs-all '(3 7-10 5-8 ; => (3 7 10 5 8 21

Ejemplo de Recursión (2/3 ;;; abs-all1: genera una lista con los valores ;;; absolutos de la lista ls, usando el procedimiento map (define abs-all1 (lambda (ls (map abs ls ; => abs-all1 (abs-all1 '(3 7-10 5-8 ; => (3 7 10 5 8 ;;; que se puede expresar directamente como: (map abs '(3 7-10 5-8 ; => (3 7 10 5 8 Ejemplo de Recursión (3/3 ;;; map1: implementa la funcion map (define map1 (lambda (proc ls (if (null? ls ( (cons (proc (car ls (map1 proc (cdr ls ; =>map1 (map1 abs '(3 7-10 5 8 ; => (3 7 10 5 8 22

Asignación let permite ligar un valor a una (nueva variable en su cuerpo (local, como define permite ligar un valor a una (nueva variable de nivel superior. Sin embargo, let y define no permiten cambiar el ligado de una variable ya existente, como lo haría una asignación. set! Permite en Scheme re-ligar a una variable existente un nuevo valor, como lo haría una asignación. Ejemplo: Asignación (define abcde '(a b c d e ; => abcde abcde ; => (a b c d e (set! abcde (cdr abcde ; => (a b c d e abcde ; => (b c d e 23

Ejemplo: Ecuación Cuadrada (1/2 (define raices-cuadradas (lambda (a b c (let ((menosb 0 (raiz 0 (divisor 1 (raiz1 0 (raiz2 0 (set! menosb (- 0 b (set! divisor (* 2 a (set! raiz (sqrt (- (* b b (* 4 (* a c (set! raiz1 (/ (+ menosb raiz divisor (set! raiz2 (/ (- menosb raiz divisor (cons raiz1 raiz2 ; => raices-cuadradas Ejemplo: Ecuación Cuadrada (2/2 (define raices-cuadradas1 (lambda (a b c (let ( (menosb (- 0 b (raiz (sqrt (- (* b b (* 4 (* a c (divisor (* 2 a (let ((raiz1 (/ (+ menosb raiz divisor (raiz2 (/ (- menosb raiz divisor (cons raiz1 raiz2 ; => raices-cuadradas1 (raices-cuadradas 2-4 -30 ; => (5. -3 (raices-cuadradas1 2-4 -30 ; => (5. -3 24

Ejemplo: Contador(1/3 ;;; definicion de un contador usando variable de ;;; nivel superior (define contador 0 ; => contador (define cuenta (lambda ( (set! contador (+ contador 1 contador ; => cuenta (cuenta ; => 1 (cuenta ; => 2 Ejemplo: Contador(2/3 ;;; la siguiente solucion usando let define una variable ;;; que no es visible fuera de su definicion (define cuenta1 (let ((cont 0 (lambda ( (set! cont (+ cont 1 cont ; => cuenta1 (cuenta1 ; => 1 (cuenta1 ; => 2 25

Ejemplo: Contador(3/3 (define hacer-contador (lambda ( (let ((cont 0 (lambda ( (set! cont (+ cont 1 cont ; => hacer-contador (define cont1 (hacer-contador ; => cont1 (define cont2 (hacer-contador ; => cont2 (cont1 ; => 1 (cont2 ; => 1 (cont1 ; => 2 (cont1 ; => 3 (cont2 ; => 2 Ejemplo: Evaluación Perezosa (1/2 ;;; lazy: evaluacion perezosa de la expresion t, la cual ;;; es solo evaluada la primera vez que se invoca. (define lazy (lambda (t (let ((val #f (flag #f (lambda ( (if (not flag (begin (set! val (t(set! flag #t val ; => lazy 26

Ejemplo: Evaluación Perezosa (2/2 (define imprime (lazy (lambda ( (display "Primera vez!" (newline "imprime: me llamaron" ; => imprime (imprime Primera vez! ; => "imprime: me llamaron" (imprime ; => "imprime: me llamaron" Ejemplo: Stack (1/2 ;;; haga-stack: es un procedimiento que permite crear un stack ;;; que tiene las operaciones: vacio?, push!, pop! y tope! (define haga-stack (lambda ( (let ((st '( (lambda (op. args (cond ((eqv? op 'vacio?(null? st ((eqv? op 'push! (begin (set! st (cons (car args st st ((eqv? op 'pop! (begin (set! st (cdr st st ((eqv? op 'tope! (car st (else "operacion no valida" ; => haga-stack 27

Ejemplo: Stack (2/2 (define st (haga-stack ; => st (st 'vacio? ; => #t (st 'push! 'perro (st 'push! 'gato (st 'push! 'canario (st 'tope! ; => (perro ; => (gato perro ; => (canario gato perro ; => canario (st 'vacio? ; => ( (st 'pop! ; => (gato perro 4.4 Aspectos más Avanzados sobre Scheme Otras formas de definición de variables y recursión de cola 28

Formas let para definición de variables Procedimientos recursivos se han definido con variables de nivel superior Hasta ahora se ha visto una forma let para definir variables locales, sólo visibles en el cuerpo Ejemplo: (let ((suma (lambda (ls (if (null? ls 0 (+ (car ls (suma (cdr ls (suma '(1 2 3 4 5 6 No es visible! Recursión con let ;;; se puede solucionar el problema entregando ;;; suma como argumento a la expresion lambda, ;;; siendo la solución más complicada (let ((suma (lambda (suma ls (if (null? ls 0 (+ (car ls (suma suma (cdr ls (suma suma '(1 2 3 4 5 6 ;=> 21 29

Aplicación de letrec ;;; letrec hace visible las variables dentro ;;; de los valores definido, permitiendo ;;; definiciones recursivas con ámbito local (letrec ((suma (lambda (ls (if (null? ls 0 (+ (car ls (suma (cdr ls (suma '(1 2 3 4 5 6 Ejemplo de Recursión Mutua (letrec ((par? (lambda (x (or (= x 0 (impar? (- x 1 (impar? (lambda (x (and (not (= x 0 (par? (- x 1 (list (par? 20 (impar? 20 ;=> (#t ( 30

Definición letrec Definiciones son también visibles en los valores de las variables Se usa principalmente para definir expresiones lambda Existe la restricción que cada valor debe ser evaluable sin necesidad de evaluar otros valores definidos (expresiones lambda lo cumplen Ejemplo de letrec (letrec ((f (lambda ( (+ x 2 (x 1 (f ;=> 3 Es válido! (letrec ((y (+ x 2 (x 1 y ;=> error No es válido! 31

Definición let con nombre ( (lambda (ls (let suma ((l ls (if (null? l 0 (+ (car l (suma (cdr l '(1 2 3 4 5 6 ;=> 21 Equivalencia entre letrec y let con nombre La expresión let con nombre: (let nombre ((var val... exp1 exp2... equivale a la expresión letrec: ((letrec ((nombre (lambda (var... exp1 exp2... nombre val... ;; fin de cuerpo de letrec 32

Recursión de Cola Cuando un llamado a procedimiento aparece al final de una expresión lambda, es un llamado de cola (no debe quedar nada por evaluar de la expresión lambda, excepto retornar el valor del llamado Recursión de cola es cuando un procedimiento hace un llamado de cola hacia si mismo, ó indirectamente a través de una serie de llamados de cola hacia si mismo. Ejemplo: Llamado de Cola Lo son los llamados a f: (lambda ( (if (g (f #f (lambda ( (or (g (f No lo son respecto a g: (lambda ( (if (g (f #f (lambda ( (or (g (f 33

Propiedad de la Recursión de Cola Scheme trata las llamadas de cola como un goto o salto de control (jump. Por lo tanto, se pueden hacer un número indefinido de llamados de cola sin causar overflow del stack. Es recomendable transformar algoritmos que producen mucho anidamiento en la recursión a uno que sólo use recursión de cola. Ejemplo1: Factorial (1/2 (sin recursión de cola (define factorial (lambda (n (let fact ((i n (if (= i 0 1 (* i (fact (- i 1 ; => factorial (factorial 5 ; => 120 n! = n * (n-1! 0! = 1 34

Ejemplo1: Factorial (2/2 (con recursión de cola (define factorial1 (lambda (n (let fact ((i n (a 1 (if (= i 0 a (fact (- i 1 (* a i ; => factorial1 (factorial1 5 ; => 120 n! = n * (n-1 * (n-2 *... 2 * 1 Ejemplo2: Fibonacci (1/2 (sin recursión de cola (define fibonacci (lambda (n (let fib ((i n (cond ((= i 0 0 ((= i 1 1 (else (+ (fib (- i 1 (fib (- i 2 ; => fibonacci (fibonacci 20 ; => 6765 fib(n = fib(n-1 + fib(n-2 fib(0 = 0 y fib(1 = 1 35

Ejemplo2: Fibonacci (2/2 (con recursión de cola (define fibonacci1 (lambda (n (if (= n 0 0 (let fib ((i n (a1 1 (a0 0 (if (= i 1 a1 (fib (- i 1 (+ a1 a0 a1 ; => fibonacci1 (fibonacci1 20 ; => 6765 Ejemplo de Factorización (define factorizar (lambda (n (let fact ((n n (i 2 (cond ((>= i n '( ((integer? (/ n i (cons i (fact (/ n i i (else (fact n (+ i 1 ;=> factorizar No recursiva de cola Recursiva de cola (factorizar 120 ;=> (2 2 2 3 5 (factorizar 37897 ;=> (37897 (factorizar 1 ;=> ( 36

Continuaciones Evaluación de expresiones Scheme implica dos decisiones: Qué evaluar? Qué hacer con el valor de la evaluación? Se denomina continuación al punto de la evaluación donde se tiene un valor y se está listo para seguir o terminar. Procedimiento call-with-current-continuation Procedimiento que se puede abreviar como call/cc call/cc se pasa como argumento formal a un procedimiento p call/cc obtiene la continuación actual y se lo pasa como argumento actual a p. 37

Procedimiento call-with-current-continuation La continuación se representa por k, donde cada vez que se aplica a un valor, éste retorna este valor a la continuación de la aplicación de call/cc. Este valor se convierte en el valor de la aplicación de call/cc. Si p retorna sin invocar k, el valor retornado por p es el valor de la aplicación de call/cc. Ejemplo de Continuación (define call/cc call-with-current-continuation ;=> Value: call/cc (call/cc (lambda (k (* 4 5 ;=> Value: 20 (call/cc (lambda (k (* 5 (+ 2 (k 7 ;=> Value: 7 38

Ejemplo 1: call/cc (define producto (lambda (ls (call/cc (lambda (salir (let prod ((ls ls (cond ((null? ls 1 ((= (car ls 0 (salir 0 (else (* (car ls(prod (cdr ls ;=> Value: producto (producto '( ;=> Value: 1 (producto '(1 2 3 4 5 ;=> Value: 120 (producto '(2 4 5 0 5 6 8 3 5 7 ;=> Value: 0 Ejemplo 2: call/cc (define list-length (lambda (ls (call/cc (lambda (retorno (letrec ((len (lambda (ls (cond ((null? ls 0 ((pair? ls (+ 1 (len (cdr ls (else (retorno #f (len ls ;=> Value: list-length (list-length '(a b c d e ;=> Value: 5 (list-length '(a. b ;=> Value: ( 39

Ejemplo de memorizar una continuación (define retry #f ;=> retry (define factorial (lambda (x (if (= x 0 (call/cc (lambda (k (set! retry k 1 (* x (factorial (- x 1 ;=> factorial (factorial 4 ;=> 24 retry ;=> #[continuation 13] (retry 2 ;=> 48 4.5 Ligado de Variables en Scheme Referencia a variables, lambda, formas let y asignación 40

a Referencia a una Variable variable retorno: valor de la variable Cualquier identificador no citada en una expresión es una palabra clave o una referencia a una variable. Una palabra clave tiene un ligado léxico; sino es una referencia a una variable. Ligado de Referencias a Variables Es un error evaluar una referencia a una variable de nivel superior antes de definirla. No lo es que una referencia a una variable aparezca dentro de una expresión no evaluada. 41

Ejemplo de Referencias a Variables list ;=> #<procedure> (define x a ;=> x (list x x ;=> (a a (let ((x b (list x x ;=> (b b (define f (lambda (x (g x ;=> f (define g (lambda (x (+ x x ;=> g (f 3 ;=> 6 b Lambda (lambda formales exp 1 exp 2... retorno: un procedimiento Permite crear procedimientos En el momento de la evaluación se ligan los parámetros formales a los actuales y las variables libres a sus valores. Parámetros formales se especifican en tres formas:lista propia o impropia o variables única Cuerpo se evalúa secuencialmente. 42

Ejemplo de Lambda ((lambda (x y (+ x y 3 4 ;=> 7 ((lambda (x. y (list x y 3 4 ;=> (3 (4 ((lambda x x 3 4 ;=> (3 4 c Ligado Local Formas más conocidas de ligado local son: let let* letrec 43

Forma let (let ((var val... exp 1 exp 2... retorno: valor de última expresión Cada variable se liga al valor correspondiente. Las expresiones de valor en la definición están fuera del ámbito de las variables. No se asume ningún orden particular de evaluación de las expresiones del cuerpo. Se recomienda su uso para valores independientes y donde no importa orden de evaluación. Forma let* (let* ((var val... exp 1 exp 2... retorno: valor de última expresión Similar a let, donde se asegura que expresiones se evalúan de izquierda a derecha. Cada expresión está dentro del ámbito de las variables de la izquierda. Se recomienda su uso si hay una dependencia lineal entre los valores o el orden de evaluación es importante. 44

Forma letrec (letrec ((var val... exp 1 exp 2... retorno: valor de última expresión Similar a let, excepto que todos los valores están dentro del ámbito de todas las variables (permite definición de procedimientos mutuamente recursivos. Orden de evaluación no está especificado. Se recomienda su uso si hay una dependencia circular entre las variables y sus valores y el orden de evaluación no es importante. Ejemplo de ligado local (let ((x 1 (y 2 (let ((x y (y x (list x y ;=> (2 1 (let ((x 1 (y 2 (let* ((x y (y x (list x y ;=> (2 2 (letrec ((suma (lambda (x (if (zero? X 0 (+ x (suma (- x 1 (suma 10 ;=> 55 45

d Definición de Variables (define var exp retorno: no especificado Normalmente se usan como definiciones de nivel superior, i.e. fuera de cualquier forma let o lambda, siendo en este caso visible en cualquier expresión donde no sea sombreada por una variable local. También están permitidas la definiciones internas al comienzo del cuerpo de una expresión lambda o derivada. La expresión: Definiciones Internas (lambda formales (define var val... exp 1 exp 2... Se transforma en: (lambda formales (letrec ((var val... exp 1 exp 2... 46

Definiciones Abreviadas para Procedimientos (define (var 0 var 1... exp 1 exp 2... retorno: no especificado (define (var 0. var r exp 1 exp 2... retorno: no especificado (define (var 0 var 1 var 2... var n.var r exp 1 exp 2... retorno: no especificado Ejemplo de Definiciones (define x 3 x ;=> 3 (define f (lambda (x (+ x 1 ;=> f (let ((x 2 (define f (lambda (y (+ y x (f 3 ;=> 5 (f 3 ;=> 4 47

Asignación (set! var exp retorno: no especificado Cambia el valor ligado a la variable se cambia al valor de la expresión. Evaluaciones posteriores evalúan al nuevo valor. set! no establece un nuevo ligado, sino que cambia uno existente. Son útiles para actualizar un estado y para crear estructuras recursivas. 4.6 Operaciones de Control en Scheme Constantes, citaciones, secuenciación, condicionales y formas repetitivas 48

a Constantes constante retorno: constante Cualquier constante evalúa hacia si mismo. Son constantes los números, booleanos, caracteres y strings. Las constantes son inmutables (no se pueden cambiar con asignación b Citaciones (quote obj (ó obj retorno: obj obj es equivalente a (quote obj Quote inhibe la evaluación de obj Citación no es necesaria para una constante 49

Cuasi- Citación (quasiquote obj (ó `obj retorno: ver explicación (unquote obj (ó,obj retorno: ver explicación (unquote-splicing obj (ó,@obj retorno: ver explicación Expresiones Cuasi-citadas quasiquote es similar a quote, salvo que permite descitar parte del texto (usando unquote o unquote-splicing. Dentro de una expresión cuasi-citada se permite la evaluación de expresiones que han sido descitadas, cuyo resultado es el que aparece en el texto. unquote o unquote-splicing son sólo válidos dentro de un quasiquote. 50

Ejemplos de Citaciones (* 2 3 ;=> (+ 2 3 `(+ 2 3 ;=> (+ 2 3 `((+ 2,(* 3 4 ;=> (+ 2 12 (let ((a 1 (b 2 `(,a.,b ;=> (1. 2 `(list,(list 1 2 3 ;=> (list (1 2 3 `(list,@(list 1 2 3 ;=> (list 1 2 3 `,(cons a b ;=> `,(cons a b `,(cons a b ;=> (a. b c Aplicación de Procedimientos (proc exp... retorno: resultado de aplicar el valor de proc a los valores de exp... Aplicación de procedimientos es la estructura básica de Scheme Orden de evaluación de expresiones no está especificado, pero se hace secuencialmente. 51

apply (apply proc obj... lista retorno: resultado de aplicar proc a los valores de obj y a los elementos de la lista apply invoca proc con obj como primer argumento, y los elementos de lista como el resto de los argumentos. Es útil cuando algunos o todos los argumentos de un procedimiento están en una lista. Ejemplos de Aplicación de Procedimientos (+ 3 4 ;=> 7 ((lambda (x x 5 ;=> 5 (apply + (5-1 3 5 ;=> 12 (apply min 5 1 3 (5-1 3 5 ;=> -1 52

d Secuenciación (begin exp1 exp2... retorno: resultado de última expresión Expresiones se evalúan de izquierda a derecha. Se usa para secuenciar asignaciones, E/S y otras operaciones que causan efectos laterales. Los cuerpos de lambda, let, let* y letrec, como también las cláusulas de cond, case y do, se tratan como se tuvieran implícitamente un begin. Ejemplo de Secuenciación (define swap-pair! (lambda (x (let ((temp (car x (set-car! x (cdr x (set-cdr! x tmp x (swap-pair! (cons a b ;=> (b. a 53

e Condicionales (if test consec alt (if test consec retorno: el valor de consec o alt según valor de test Si no se especifica alternativa y test evalúa en falso, resultado no está especificado. not (not obj retorno: not es equivalente a: #t si obj es falso, sino #f (lambda (x (if x #f #t El estándar ANSI/IEEE permite que ( y #f sean equivalente, retornando #t para (not ( 54

and (and exp... retorno: ver explicación Evalúa expresiones de izquierda a derecha y se detiene tan pronto alguna evalúa en falso. Se retorna el valor de la última evaluación. or (or exp... retorno: ver explicación Evalúa expresiones de izquierda a derecha y se detiene tan pronto alguna evalúa en verdadero. Se retorna el valor de la última evaluación. 55

cond (1/2 (cond cla 1 cla 2... retorno: ver explicación Cada cláusula, excepto la última, tiene la forma: (test (test exp 1 exp 2 (test => exp La última cláusula tiene alguna de las formas (else exp 1 exp 2 anteriores o: cond (2/2 Las cláusulas se evalúan en orden hasta que alguna evalúa en verdadero, o hasta que se agoten Si el test de evalúa verdadero, el valor de test es retornado. Si el test de evalúa verdadero, el valor de la última expresión es retornado. Si el test de evalúa verdadero, es aplicar el procedimiento de la expresión a test (un argumento Si todas las cláusulas evalúan en falso: si hay else, se retorna valor de la última expresión si no hay else, valor no está especificado 56

Ejemplo de cond (define nota (lambda (x (cond ((not (symbol? x ((assq x ((juan. 68(maria. 98 (diego. 45(lucia. 55 => cdr (else 0 (nota 40 ;=> #t (nota maria ;=> 98 (nota anastasio ;=> 0 case (case exp 0 cla 1 cla 2... retorno: ver explicación Cada cláusula tiene la forma: ((clave...exp 1 exp 2 Siendo las claves datos diferentes. Se puede poner al final una cláusula que calza todo: (else exp 1 exp 2 exp 0 se evalúa, luego se busca alguna clave que calce con este valor; el resultado es el valor de la última expresión. 57

Ejemplo de case (define f (lambda (x (case x ((1 3 5 7 9 impar ((0 2 4 6 8 par (else fuera-de-rango (f 3 ;=> impar (f 8 ;=> par (f 14 ;=> fuera-de-rango f Recursión e Iteración (let nombre ((var val... exp 1 exp 2... retorno:valor de última expresión Es un constructor general de iteración y recursión. Las variables var son visibles dentro del cuerpo, como en la forma común de let. nombre es ligado a un procedimiento que puede iterar o llamarse recursivamente. En un nuevo llamado, los argumentos son los nuevos valores de las variables var 58

Ejemplo de let con nombre (define divisores ;;; sin recursión de cola (lambda (n (let div ((i 2 (cond ((>= i n ( ((integer? (/ n i (cons i (div (/ n i i (else (div n (+ i 1 (define divisores ;;; con recursión de cola (lambda (n (let div ((i (- n 1 (ls ( (cond ((<= i 1 ( ((integer? (/ n i (div i (cons i ls (else (div (- i 1 ls do (do ((var val nuevo... (test res... exp... retorno:valor de último res Permite una forma iterativa simple. Lar variables var se ligan inicialmente a val, y son re-ligadas a nuevo en cada iteración posterior. En cada paso se evalúa test. Si evalúa como #t : se termina evaluando en secuencia res y retornando valor de última expresión de res. #f: se evalúa en secuencia exp... y se vuelve a iterar re-ligando variables a nuevos valores. 59

Ejemplo de do (define factorial (lambda (n (do ( (i n (- i 1 ;; variable i (a 1 (* a i ;; variable a ((zero? i a ;; test (define divisores (lambda (n (do ((i 2 (+ i 1 ;; variable i (ls ( ;; variable ls (if (integer? (/ n i (cons i ls ls ((>= i n ls ;; test for-each (for-each proc lista 1 lista 2... retorno:no especificado Similar a map, pero no crea ni retorna una lista con los resultados. En cambio, si garantiza orden de aplicación de proc a los elementos de las listas de izquierda a derecha. 60

Ejemplo de for-each (define comparar (lambda (ls1 ls2 (let ((cont 0 (for-each (lambda (x y (if (= x y (set! cont (+ cont 1 ls1 ls2 cont (comparar (1 2 3 4 5 6 (2 3 3 4 7 6 ;=> 3 g Mapping (map proc lista 1 lista 2... retorno:lista de resultados Las listas deben ser del mismo largo. proc debe aceptar un número de argumentos igual al número de listas. map aplica repetitivamente proc tomando como parámetros un elemento de cada lista. No está especificado el orden en que se aplica proc a los elementos de las listas. 61

Ejemplo de map (map (lambda (x y (sqrt (* x x (* y y (3 5 (4 12 ;=> (5 13 h Evaluación Retardada (delay exp retorno:una promesa (force promesa retorno:resultado de forzar la promesa delay con force se usan juntos para permitir una evaluación perezosa, ahorrando computación. La primera vez que se fuerza la promesa se evalúa exp, memorizando su valor; forzados posteriores retornan el valor memorizado. 62

Ejemplo de Evaluación Retardada ;;; define un stream infinito de números naturales (define stream-car (lambda (s (car (force s (define stream-cdr (lambda (s (cdr (force s (define contadores (let prox ((n 1 (delay (cons n (prox (+ n 1 (stream-car contadores ;=> 1 (stream-car (stream-cdr contadores ;=> 2 i Evaluación (eval obj retorno: evaluación de obj como un programa Scheme obj debe ser un programa válido de Scheme. El ámbito actual no es visible a obj, comportándose éste como si estuviera en un nivel superior de otro ambiente. No pertenece al estándar de ANSI/IEEE. 63

Ejemplo de eval (eval 3 ;=> 3 (eval (+ 3 4 ;=> 7 (eval (list + 3 4 ;=> 7 4.7 Operaciones sobre Objetos en Scheme Equivalencias y predicados de tipos, listas, números, caracteres, strings y vectores 64

a Equivalencias (eq? obj 1 obj 2 retorno: #t si son idénticos (eqv? obj 1 obj 2 retorno: #t si son equivalentes eqv? es similar a eq?, salvo que no es dependiente de la implementación, pero es algo más costoso. eq? no permite comparar en forma fiable números equal? (equal? obj 1 obj 2 retorno: #t si tienen la misma estructura y contenido equal? es similar a eqv?, salvo que se aplica también para strings, pares y vectores. Es más costoso que eqv? y eq?, 65

Ejemplos de Equivalencia (eq? a a ;=> #t (eq? 3.1 3.1 ;=> ( (eq? (cons a b(cons a b ;=> ( (eqv? a a ;=> #t (eqv? 3.1 3.1 ;=> #t (eqv? (cons a b(cons a b ;=> ( (equal? a a ;=> #t (equal? 3.1 3.1 ;=> #t (equal? (cons a b(cons a b ;=> #t b Predicados de Tipos (boolean? obj retorno: #t si obj #t o diferente de #f (null? obj retorno: #t si obj #f o lista vacia (pair? obj retorno: #t si obj es un par 66

Tipos de Números (number? obj retorno: #t si obj es número (complex? obj retorno: #t si obj es número complejo (real? obj retorno: #t si obj es número real (rational? obj retorno: #t si obj es número racional (integer? obj retorno: #t si obj es número entero Otros Tipos (char? obj retorno: #t si obj es un caracter (string? obj retorno: #t si obj es un string (vector? obj retorno: #t si obj es un vector (symbol? obj retorno: #t si obj es un símbolo (procedure? obj retorno: #t si obj es un procedimiento 67

c Listas El par es la estructura más fundamental de los tipos de objetos Los pares normalmente se usan para construir listas Las listas son secuencias ordenadas donde cada elemento ocupa el car de un par y el cdr del par del último elemento es la lista vacía. Si no se cumple lo anterior, es una lista impropia Operadores Básicos con Listas (list obj... retorno: una lista de elementos obj... (list? obj retorno: #t si obj es una lista propia (length? list retorno: el número de elementos de list 68

Otros Operadores con Listas (list-ref list n retorno: elemento #n (basado en 0 de list (list-tail list n retorno:el resto de list a partir de elemento #n (append list... retorno: concatenación de list... (reverse list retorno: list en orden invertido Membresía en Listas (memq obj list retorno:el resto de list a partir de elemento obj si es encontrado, sino #f (memv obj list retorno:el resto de list a partir de elemento obj si es encontrado, sino #f (member obj list retorno:el resto de list a partir de elemento obj si es encontrado, sino #f Usan eq? y eqv? y equal? respectivamente 69

d Listas Asociativos Una lista asociativa (alist es una lista propia cuyos elementos son pares. Un par tiene la forma (clave. valor Asociaciones son útiles para almacenar información (valor relacionada con un objeto (clave Operadores con Listas Asociativos (assq obj alist retorno: primer elemento de alist cuyo car es equivalente a obj, sino #f (assv obj alist retorno: primer elemento de alist cuyo car es equivalente a obj, sino #f (assoc obj alist retorno: primer elemento de alist cuyo car es equivalente a obj, sino #f Usan eq? y eqv? y equal? respectivamente 70

e Números Scheme soporta enteros, racionales, reales y complejos (que definen una jerarquía Los números pueden ser exactos o inexactos Enteros y racionales pueden soportan precisión arbitraria Números inexactos se representan en punto flotante Los complejos se representan como un par, usando coordenadas polares o rectangulares Operadores con Números (exact? num retorno: #t si num es exacto (inexact? num retorno: #t si num es inexacto (= num 1 num 2... retorno: #t si los números son iguales (op real 1 real 2... retorno: #t si los números cumplen la relación op, con op en {<, >, <=,>=} (no está definido para complejos 71

Operadores Aritméticos (+ num... retorno: la suma de los argumentos num... (- num retorno: cambio de signo de num (- num 1 num 2... retorno: substracción a num 1 de num 2... (* num... retorno: la multiplicación de num... (/ num retorno: recíproco multiplicativo de num (/ num 1 num 2 num 3... retorno: la división de num 1 por la multiplicación de num 2... Predicados con Números (zero? num retorno: #t si num es cero (positive? num retorno: #t si num es positivo (negative? num retorno: #t si num es negativo (even? num retorno: #t si num es par (odd? num retorno: #t si num es impar 72

Operadores con Enteros (quotient int 1 int 2 retorno: el cuociente de int 1 y int 2 (remainder int 1 int 2 retorno: el residuo de int 1 y int 2 (modulo int 1 int 2 retorno: el módulo entero de int 1 y int 2 (gcd int... retorno: máximo común divisor de num (lcm int... retorno: mínimo común múltiplo de num... Operadores con Reales (truncate real retorno: truncar a entero hacia cero (round real retorno: rondear a entero más cercano (abs real retorno: valor absoluto (max real... retorno: máximo de real... (min real... retorno: mínimo de real... 73

Funciones Matemáticas (sqrt num retorno: raíz cuadrada de num (exp num retorno: e elevado a la potencia de num (log num retorno: el logaritmo natural de num (sin num retorno: el seno de num (cos num retorno: el coseno de num (tan num retorno: la tangente de num f Caracteres Representan objetos atómicos (letras, números, caracteres especiales Se escriben con el prefijo #\ Ejemplos: #\a #\newline #\space carácter a cambio de línea espacio en blanco 74

Predicados de Caracteres (char=? char 1 char 2... (char<? char 1 char 2... (char>? char 1 char 2... (char<=? char 1 char 2... (char>=? char 1 char 2... retorno: #t si relación es verdadera, sino #f Relaciones son sensibles a mayúsculas Operadores char-ci@? son insensibles Otros Operadores con Caracteres (char-alphabetic? char retorno: #t si char es letra (char-number? char retorno: #t si char es número (char-lower-case? letter retorno: #t si char es letra minúscula (char-upper-case? letter retorno: #t si char es letra mayúscula (char->integer char retorno: código del carácter char (integer->char int retorno: carácter con código int 75

g Strings Representan cadenas o secuencias de caracteres Se emplean en mensajes o buffers de caracteres Se escriben entre citación doble; doble citación se introduce en el texto con \ Se indexan con base en 0 Ejemplo: Hola \ Ohhh\ Predicados de Strings (string=? string 1 string 2... (string<? string 1 string 2... (string>? string 1 string 2... (string<=? string 1 string 2... (string>=? string 1 string 2... retorno: #t si relación es verdadera, sino #f Relaciones son sensibles a mayúsculas Operadores string-ci@? son insensibles 76

Otros Operadores con Strings (string char... retorno: un string que contiene char... (make-string n retorno: un string de n caracteres (indefinido (string-length string retorno: largo del string (string-ref string n retorno: el carácter n (desde 0 del string (string-set! string n char acción: cambia el carácter n de string a char (string-copy string retorno: una copia de string (string-append string... retorno: concatenación de string... h Vectores Forma más conveniente y eficiente de listas en algunas aplicaciones A diferencia de listas, el acceso a un elemento se hace en tiempo constante Al igual que strings, se referencian con base 0 Elementos pueden ser de cualquier tipo Se escriben como lista, pero precedidos por # Ejemplo: #(a b c 77

Operadores con Vectores (vector obj... retorno: un vector con objetos obj... (make-vector n retorno: un vector de largo n (vector-length vector retorno: largo de vector (vector-ref vector n retorno: el elemento n de vector Más Operadores con Vectores (vector-set! vector n obj acción: define elmto n de vector como obj (vector-fill! vector obj acción: reemplaza cada elemento de vector con obj (vector->list vector retorno: una lista con elementos de vector (list->vector list retorno: una vector con elementos de lista list 78

4.8 Operaciones de Entrada y Salida en Scheme Entrada y Salida Toda E/S se realiza por puertos. Un puertos es un puntero a un flujo (posiblemente infinito de caracteres (e.g. archivo Un puerto es un objeto de primera clase El sistema tiene dos puertos por defecto: entrada y salida estándar (normalmente es el terminal en un ambiente interactivo Cuando se agotan los datos de entrada se retorna el objeto especial eof 79

Operaciones de Entrada (1/2 (input-port? obj retorno: #t si obj es puerto de entrada (current-input-port retorno: puerto de entrada actual (open-input-file filename retorno: nuevo puerto de entrada asociado a archivo filename (call-with-input-file file proc acción: abre file y llama a proc con puerto abierto como parámetro; luego cierra puerto retorno: valor de evaluación de proc (close-input-port input-port acción: cierra puerto de entrada Operaciones de Entrada (2/2 (eof-object? obj retorno: #t si obj es fin de archivo (read (read input-port retorno: próximo objeto de input-port (read-char (read-char input-port retorno: próximo carácter de input-port (con consumo (peek-char (peek-char input-port retorno: próximo carácter de input-port (sin consumo 80

Ejemplos de Entrada (input-port? (a b c => unspecified (input-port? (current-input-port => #t (input-port? (open-input-file f.dat => #t (let ((p (open-input-file mi_archivo (let leer ((x (read p (if (eof-object? x (begin (close-input-port p ( (cons x (leer (read x Otro Ejemplo de Entrada (define read-word (lambda (p (list->string (let leer_entrada ( (let ((c (peek-char p (cond ((eof-object? c '( ((char-alphabetic? c (read-char p (cons c (leer_entrada (else '( ;=> read-word (read-word (current-input-port hola ;=> "hola" 81

Operaciones de Salida (1/2 (output-port? obj retorno: #t si obj es puerto de salida (current-output-port retorno: puerto de salida actual (open-output-file file retorno: nueva puerto de salida asociado a archivo file (call-with-output-file file proc acción: abre file y llama a proc con puerto abierto como parámetro; luego cierra puerto retorno: valor de evaluación de proc (close-output-port output-port acción: cierra puerto de salida Operaciones de Salida (2/2 (write obj (write obj output-port acción: escribe obj a output-port (display obj (display obj output-port acción: escribe obj a output-port (write-char char (write-char char output-port acción: escribe char a output-port (newline (newline output-port acción: escribe nueva línea a output-port 82

Observaciones a E/S write escribe objetos que luego pueden ser leídos con read Strings se escriben con citación doble Un carácter se escribe con prefijo #\ display se usa normalmente para escribir objetos que no serán leídos Strings y caracteres no escriben doble citación o #\ write-char y read-char escriben y leen un único carácter sin usar #\ Ejemplo de E/S (define copy-file (lambda (infile outfile (call-with-input-file infile (lambda (iport (call-with-output-file outfile (lambda (oport (do ((c (read-char iport (read-char iport ((eof-object? c (write-char c oport ;=> copy-file (copy-file infile outfile ;=> #t 83

Operaciones Especiales de E/S (transcript-on file acción: inicia registro en file la sesión interactiva de Scheme (transcript-off acción: termina de registrar sesión (load file acción: carga file leyendo y evaluando secuencialmente las expresiones contenidas. 84