Paso de parámetros y arreglos. Las aplicaciones (llamadas a procedimiento) Resolución de nombres (gracias al establecimiento de un ambiente) Condicionamiento.

Slides:



Advertisements
Presentaciones similares
Programación de Computadores
Advertisements

III - Gestión de memoria
U NIDAD 2 L ENGUAJE DE DEFINICIÓN DE DATOS (DDL) 1.
Programación I Teoría III
Interpretando objetos
MANEJO DE ARRAYS EN C.
Informática II Prof. Dr. Gustavo Patiño MJ
ALGORÍTMICA Dpto. Ingeniería de Sistemas y Automática
Teoría de lenguajes y compiladores
Tema 3. Optimización de Código
Composición Interna de un Procesador
Funciones en lenguaje C
CI TEORIA semana 8 Subprogramas o funciones Definición de funciones.

1 Procedimientos Es un conjunto de sentencias incluidas entre las declaraciones Sub o Function y End Sub/Function VB utiliza varios tipos de procedimientos:
Teoría de lenguajes y compiladores
TRAMPAS EN EL DISEÑO DE LENGUAJES CON RELACIÓN A LOS NOMBRES - REGLAS DE ALCANCE - COMPILACIÓN POR SEPARADO CONTROL DE FLUJO - EVALUACIÓN DE EXPRESIONES.
Tema 6: Clases Antonio J. Sierra.
MODOS DE DIRECCIONAMIENTO
Semana 5 Subprogramas..
ARQUITECTURAS SIMD TIPOS
TIPOS DE DATOS ABSTRACTOS
ESTRUCTURA DE DATOS EN JAVA
COMPUTACION 2009 Clase 6 Clase 7.
Clase 10: Estructuras de datos y arreglos.
Extensiones sintácticas Revisaremos formas especiales que son sintácticamente equivalentes a patrones que son expresables en términos de formas básicas.
Tema 10.3: Asignación de Espacio No Contiguo. Tema 10.3: 2 Silberschatz, Galvin and Gagne ©2005 Fundamentos de los Computadores (ITT, Sist. Electr.),
Programación en Pascal
(Organización y Manejo de Archivos)
ELO3201 Contenedores Biblioteca Estándar de Templates Agustín J. González ELO320 Contenido Contenedores: Vector, List, Deque, Stack, Queue, Priority Queue,
Asignación de Espacio No Contiguo
Agenda Clase 16 Motivación e Historia de la Programación Funcional y la Programación Lógica. Concepto y Características de la Programación Funcional. Ventajas.
Programación Básica con NQC Patricio A. Castillo Pizarro 25/08/2007.
Material de apoyo Unidad 4 Estructura de datos
Tipos de Datos. Entrada-Salida.. La entrada-salida (I/O) le permite a un programa comunicarse con el mundo exterior. Esta comunicación puede realizarse.
Teoría – Alejandro Gonzalez
NVA-LNG1 3. SENTENCIAS. NVA-LNG2 Asignación Es una sentencia que almacena: el valor del argumento ubicado a la derecha del símbolo que la representa En.
EXPRESIONES Y SENTENCIAS
Ada 2º Parte (variables, ámbitos , subrutinas , tipos abstractos de datos y excepciones)
Programación de Sistemas
APRENDIZ: SANDRA L. CAICEDO C. ORDEN: 20194
Informática Ingeniería en Electrónica y Automática Industrial
1 Samba: Un lenguaje funcional perezoso Presentación del lenguaje: qué es un programa Samba definiciones locales abstracciones lambda Tipos inductivos:
1 Compilación, pereza y expresiones let(rec) 2 Compilando un programa Describiremos un compilador para la máquina minimal usando un conjunto de esquemas.
Estructura general de un programa en el servidor de Bases de Datos.
Programación Procedural y Recursiva en C++
Estructura de los Sistemas Operativos
Objetivo Mostrar los fundamentos de la programación a través de ejemplos y prácticas utilizadas cotidianamente en el desarrollo de aplicaciones.
COLEGIO DE BACHILLERES PLANTEL 13 XOCHIMILCO-TEPEPAN MATERIA:TIC EQUIPO:21 PRESENTACION: BASE DE DATOS ALUMNAS: Adán Millán Sánchez.
CARACTERÍSTICAS Es un lenguaje de programación estructurado de propósito general. Está estrechamente asociado al sistema operativo UNIX, ya que el propio.
SEMANA 01_2.
Visual Basic FUNCIONES Y PROCEDIMIENTOS
Teoría de lenguajes y compiladores
2008 Escuela de Informática y Telecomunicaciones, DuocUC Escuela de Informática y Telecomunicaciones Clase 9: Funciones, variables y arreglos en BASH Nombre.
Capítulo 2 “Subprogramas/Funciones - Arreglos”
Presente un cuestionario con los aspectos mas importantes sobre los
UNIDAD 4: Introducción a la Lógica Computacional Objetivo : Interpretar y aplicar adecuadamente los fundamentos básicos de la estructura y funcionamiento.
Introducción a los TADs
MIA - Grupo 5 Unidad 2.
Programación de Sistemas
 Las funciones son un conjunto de instrucciones que realizan una tarea específica. En general toman unos valores de entrada, llamados parámetros y proporcionan.
PARADIGMA Es un marco de referencia que impone reglas sobre cómo se deben hacer las cosas. CONCEPTO DE PARADIGMA DE PROGRAMACION colección de modelos conceptuales.
MEMORIA DINÁMICA.
JOSE ALBERTO JIMENEZ JIMENEZ KATTY HIPOLITO. 7.1 INTRODUCCION AL LENGUAJE EMSAMBLADOR.
Prof. Manuel B. Sánchez. Declaración de Objetos Una vez que la clase ha sido implementada se pueden declarar objetos como variables locales de métodos.
La programación modular es un paradigma de programación que consiste en dividir un programa en módulos o subprogramas con el fin de hacerlo más legible.
Métodos en Java. Estructura de un programa en Java ► La relación con la vida misma la podemos ver en el siguiente comentario: Imaginemos que dos clases.
Lenguaje ensamblador Resumen en diapositivas
Omar Herrera Caamal Rigoberto Lizárraga Luis Cetina Luna.
Departamento de Informática Universidad Técnica Federico Santa María Lenguajes Funcionales Francisco Bórquez Departamento de Informática Universidad Técnica.
Transcripción de la presentación:

Paso de parámetros y arreglos

Las aplicaciones (llamadas a procedimiento) Resolución de nombres (gracias al establecimiento de un ambiente) Condicionamiento de la ejecución. Creación de variables locales. Creación de procedimientos por parte del usuario, Asignación de variables Recursión Alcance dinámico y asignación o afectacion dinámica Gracias a los interpretes hemos explorado varias características que ofrecen los lenguajes de programación dentro de las cuales encontramos:

Otras características de los LP Modificando nuestro interprete podremos: –Seguir explorando las características de los LP’s –Expresar alternativas semánticas para los LP de una manera clara y precisa de forma a enfantizar sus diferencias esenciales.

Otras características de los LP Extensiones a nuetro interprete para estas sesiones: –Manejo de arreglos. –Paso de parámetros. Llamadas por Valor. Llamadas por referencia. Llamadas por el valor del resultado. Llamadas por resultado. Llamadas por nombre (o por retraso). Llamadas por necesidad. –Parámetros opcionales –Parámetros por nombre (vs. posición)

Añadiendo arreglos Muchos lenguajes de programación incluyen estructuras de datos compuestos de multiples elementos conocidos como agregados. En Scheme encontramos los siguientes agregados: –Pares. –Vectores. –Cadenas de caracteres. Existen dos representaciones para los agregados: –Directa (ej. arreglos en pascal). El paso de un parámetro de este tipo a un procedimiento se hace por valor i.e. se hace una copia del agregado. –Indirecta (ej. C). El paso de un parámetro de este tipo a un procedimiento se hace por referencia i.e. se envía un apuntador al agregado que se quiere enviar como parámetro.

Añadiendo arreglos 1.Una nueva forma que permita la creación de arreglos y su asociación a una varable. 2.Una expresión que permita la asociación local de una variable con un arreglo. 3.Una expresión que permita acceder a un elemento de un arreglo. 4.Una expresión que permita la asignación de valores a un elemento de un arreglo. Agreguemos a nuestro interprete las siguientes extensiones para el manejo de arreglos:

Sintaxis abstracta y concreta para la adición de arreglos al interprete ::= definearray definearray (var len-exp) ::= letarray in letarray (arraydecls body) | [ ]arrayref (array index) | [ ] :=arrayassign (array index exp) ::= | ( ) ::= {;<arraydecl)} * decl (var exp) Un arreglo es una secuencia de celdas las cuales contienen valores expresados (representación indirecta): Arreglo = {Celda(Valor expresado)} Valor expresado = Número + Procedimiento + Arreglo Valor denotado = Celda (Valor expresado)

ADT para el arreglo (define make-array (lambda (length) (let ((array (make-vector (+ length 1)))) (vector-set! array 0 '*array*) array))) (define array? (lambda (x) (and (vector? x) (eq? (vector-ref x 0) '*array*)))) (define array-ref (lambda (array index) (vector-ref array (+ index 1)))) (define array-set! (lambda (array index value) (vector-set! array (+ index 1) value)))

ADT para el arreglo… (define array-whole-set! (lambda (dest-array source-array) (let ((source-len (vector-length source-array))) (letrec ((loop (lambda (n) (if (< n source-len) (begin (vector-set! dest-array n (vector-ref source-array n)) (loop (+ n 1))))))) (loop 1))))) (define array-copy (lambda (array) (let ((new-array (make-array (- (vector-length array) 1)))) (array-whole-set! new-array array) new-array)))

Modifs al interprete para manejo de arreglos (define eval-exp (lambda (exp env) (variant-case exp (varref (var) (denoted->expressed (apply-env env var))) (app (rator rands) (apply-proc (eval-rator rator env) (eval-rands rands env))) (varassign (var exp) (denoted-value-assign! (apply-env env var) (eval-exp exp env))) (letarray (arraydecls body) (eval-exp body (extend-env (map decl->var arraydecls) (map (lambda (decl) (do-letarray (eval-exp (decl->exp decl) env))) arraydecls) env))) (arrayref (array index) (array-ref (eval-array-exp array env) (eval-exp index env))) (arrayassign (array index exp) (arrayassign (array index exp) (array-set! (eval-array-exp array env) (eval-exp index env) (eval-exp exp env))) (else...))))

Modifs al interprete para manejo de arreglos (define eval-rator (lambda (rator env) (eval-exp rator env))) (define eval-rands (lambda (rands env) (map (lambda (rand) (eval-rand rand env)) rands))) (define eval-rand (lambda (exp env) (expressed->denoted (eval-exp exp env)))) (define apply-proc (lambda (proc args) (variant-case proc (prim-proc (prim-op) (apply-prim-op prim-op (map denoted->expressed args))) (closure (formals body env) (eval-exp body (extend-env formals args env))) (else (error "Invalid procedure:" proc)))))

Paso por valor de arreglos (representación indirecta ) (define denoted->expressed cell-ref) (define denoted-value-assign! cell-set!) (define do-letarray (compose make-cell make-array)) (define eval-array-exp eval-exp) (define expressed->denoted make-cell)

Representación de celdas (define cell-tag "cell") (define make-cell (lambda (x) (vector cell-tag x))) (define cell? (lambda (x) (and (vector? x) (= (vector-length x) 2) (eq? (vector-ref x 0) cell-tag)))) (define cell-ref (lambda (x) (if (cell? x) (vector-ref x 1) (error "Invalid argument to cell-ref:" x)))) (define cell-set! (lambda (x value) (if (cell? x) (vector-set! x 1 value) (error "Invalid argument to cell-set!:" x)))) (define cell-swap! (lambda (cell-1 cell-2) (let ((temp (cell-ref cell-1))) (cell-set! cell-1 (cell-ref cell-2)) (cell-set! cell-2 temp))))

Arreglos representación directa Arreglo = {Celda(Número + Procedimiento)} Valor expresado = Número + Procedimiento + Arreglo Valor denotado = Celda (Número)+Celda (Procedimiento)+Arreglo En la reprresentación directa cuando un arreglo es pasado por valor, el parámetro formal es afectado a una copia de la secuencia de valores. En caso de que exista una asignación dentro del procedimeinto, solo la copia local del arreglo se verá afectada.

Paso por valor de arreglos (representación directa ) Habrá que modificar el procedimiento array-set! de manera a que no pueda existir un arreglo dentro de otro: (define array-set! (lambda (array index value) (if (array? value) (error "Cannot assign array to array element" value) (vector-set! array (+ index 1) value))))

Paso por valor de arreglos (representación directa )… (define denoted->expressed (lambda (den-val) (if (array? den-val) den-val (cell-ref den-val)))) (define denoted-value-assign! (lambda (den-val exp-val) (cond ((not (array? den-val)) (cell-set! den-val exp-val)) ((array? exp-val) (array-whole-set! den-val exp-val)) (else (error "Must assign array:" den-val))))) (define do-letarray make-array) (define eval-array-exp eval-exp) (define expressed->denoted (lambda (exp-val) (if (array? exp-val) (array-copy exp-val) (make-cell exp-val))))

Representación indirecta Vs. directa letarray u[3]; v[2] in begin u[0] := 5; u[1] := 6; u[2] := 4; v[0] := 3; v[1] := 8; let p = proc (x) begin x[1] : =7; x := v; x[1] := 9 end in p(u) end xuv (a) xuv xu v (b) xu v

Llamada por referencia En Scheme todo tipo de dato se pasa por valor. Usa la representación directa para los escalares tal que los valores numéricos. Para los agregados usa una representación indirecta por razones de eficiencia. En algunas ocasiones es necesario o conveniente el poder asignar o afectar los valores asociados a los parámetros con el fin de comunicarle un resultado al procedimiento llamante. Esto sería un efecto secundario que a veces es dificil de entender

Los alias y el paso por referencia Algunos problemas provocados por el paso por referencia los evidencia el siguiente programa (suponga que los parámetros son pasados por referencia).  define swap = proc (x, y) begin x := +(x, y) y := -(x, y); x := -(x, y) end;  define b =1;  define c = 2;  swap(b, c);  b; 2  c; 1  swap(b,b)  b 0

Modelando paso de parámetros por referencia… Para realizar el paso de parámetros por referencia (en cuanto a variables no del tipo de arreglos) solamente es necesario cambiar: :: = a ::= (define eval-rand (lambda (rand env) (variant-case rand (varref (var) (apply-env env var)) (else (error "Invalid operand:" rand)))))

Modelando paso de parámetros por referencia… En una implementación típica, el paso por referencia de un elemento de un arreglo se realiza a través de un apuntador. En Scheme no es posible obtener un apuntador a un elemento de un arreglo (no existe un operador & como en C). Es necesario crear un nuevo registro para lograrlo: (define-record ae (array index)) Nuestros operandos tendrian entonces la siguiente forma ::= | [ ] |

Modelando paso de parámetros por referencia… Las siguientes modificaciones a nuetro interprete son necesarias: (define eval-rand (lambda (rand env) (variant-case rand (varref (var) (apply-env env var)) (arrayref (array index) (make-ae (eval-array-exp array env) (eval-exp index env))) (else (make-cell (eval-exp rand env)))))) (define denoted->expressed (lambda (den-val) (cond ((cell? den-val) (cell-ref den-val)) ((ae? den-val) (array-ref (ae->array den-val) (ae->index den-val))) (else (error "Can't dereference denoted value:" den-val)))))

Modelando paso de parámetros por referencia… (define denoted-value-assign! (lambda (den-val val) (cond ((cell? den-val) (cell-set! den-val val)) ((ae? den-val) (array-set! (ae->array den-val) (ae->index den-val) val)) (else (error "Can't assign to denoted value:" den-val)))))

Modelando paso de parámetros por referencia… letarray u[3]; v[2] in begin u[0] := 5; u[1] := 6; u[2] := 4; v[0] := 3; v[1] := 8; let p = proc (x) begin x[1] : =7; x := v; x[1] := 9 end in p(u) end x, uv (a) x, uv x u v (b) u v x

Llamadas por el valor del resultado y llamadas por resultado Es de uso frecuente que el compilador aloje en localidades específicas (conocidas) de memoria, los parámetros pasados por valor de manera a que los procedimientos los accedan de forma directa. En llamadas por referencia, esto no sucede así y las localidades específicas no se conocen sino hasta la propia invocación del procedimiento. Las llamadas a procedimiento por referencia son menos eficientes. Las llamadas por el valor del resultado combinan: La eficiencia al acceder parámetros que se pasan por valor. La habilidad de regresar información via los parámetros.

Llamadas por el valor del resultado y llamadas por resultado El parametro que es pasado por llamada por el valor del resultado es copiado a una localidad específica de la memoria al momento de la invocación del procedimiento. El valor final del parámetro que es pasado por llamada por el valor del resultado es recopiado a su localidad original al finalizar el procedimeinto. Las llamadas por el valor de resultado son más eficientes a expensas de un proceso menos eficiente de invocación y termino de procedimiento. Depende de los accesos que el procedimeinto haga del parámetro en cuestión.

Llamadas por el valor del resultado y llamadas por resultado El paso por llamadas por el valor del resultado no sufre de los problemas de “alias”. En la ausencia del problema de “alias” las llamadas por el valor del resultado tiene el mismo efecto que las llamadas por referencia. Normalmente es el compilador quien hace la elección de que tipo de llamada utilizar. Las llamadas por resultado tienen las mismas características que las llamadas por el valor del resultado excepto que solo se usan para transferir información del procedimiento llamante al llamado (ej. Un código de error) Las llamadas por valor, las llamadas por el valor del resultado y las llamadas por resultado se conocen como llamadas por copia.

Valores expresados o denotados ? Muchas de las diferencias en los lenguajes de programación estrivan en el manejo de: Los valores expresados, los cuales son productos de la evaluación de una expresión. Los valores denotados (aquellos valore que guardamos en memoria) normalmente más ricos que los expresados Los valores “L-values” que aparecen del lado izquierdo en una asignación.

Valores expresados o denotados ?... En lenguajes imperativos tradicionales las expresiones ocurren en el lado derecho (R-values) de las asignaciones. => El conjunto de valores expresados corresponde al conjunto de valores almacenables en una localidad de memoria. En algunos casos es necesario restringir los valores expresados de manera a evitar duplicaciones (ej. cunado se representan de manera directa los agregados) Ejemplo: Valor expresado = Numero Valor denotado = L-value + Arreglos + Procedimientos

Valores expresados o denotados ?... Estudiando los valores expresados y denotados de un lenguaje proporcionan un profundo conocimiento de la estructura del lenguaje de programación. La estructura usada para el almacenamiento y manejo de los valores por un lenguaje de programación, determina en buena parte: El poder de expresividad del lenguaje. El nivel de eficiencia. La estrategia de implementación.

Llamadas por nombre y llamadas por necesidad. Algunas LP no evalúan los argumentos antes de pasarlas a un procedimiento, i.e.retrasan su evaluación: No realizar evaluaciones innecesarias. Evitar computaciones sin terminación (recuerde el ejemplo en conversion  ).

Llamadas por nombre y por necesidad. Una de las formas para retrasar la evaluación del operando es pasar el arbol sintáctico (o codigo compilado) representando al operando. De la misma manera que para la definición de los procedimientos habrá que crear una “closure” (su ambiente al momento de definirlo) para cada argumento. Los “Closures” usados para retrasar la evaluación de los argumentos son conocidos como “thunks”. El paso de parámetros en donde la evaluación de los argumentos es retrasado usando “thunk” se conoce como llamadas por nombre. Almacenando la evaluación (cuando sea necesaria) de un parámetro para evitar calculo redundannte se conoce como llamadas por necesidad.

Argumentos opcionales y por palabra clave En muchos LP los parámetros formales son asociados con los argumentos de acuerdo a su posición: El n-esimo parametro formal es asociado al n-esimo argumento. Es también posible establecer el paso de los argumentos por palabra clave tal y como ocurre en muchos comandos de algunos sistemas operativos (ej. dir /a:d cc –l pthread) Con operandos por palabra clave es necesario recordar la palabra clave. Con operandos por posición es necesario recordar la posición correspondiente a cada operando

Argumentos opcionales y por palabra clave Existen lenguajes de programación que permiten establecer valores por omisión para ciertos argumentos.  conveniente para el caso en que el procedimiento se llama en repetidas ocasiones con el mismo valor para ese argumento.

Argumentos opcionales y por palabra clave Para el caso de que los argumento que se pasen por posición es conveniente que los argumentos opcionales se pongan al final como en el caso de (lambda (n. m) …). Al utilizar paso de parámetros por palabra clave y argumentos opcionales solo se indicarían las palabras claves de aquellos argumentos obligatorios y de aquellos cuyo valor por omisión no nos convenga.