Universidad Simón Bolívar Departamento de Computación y Tecnología de la Información CI3641 Lenguajes de Programación I Guía Corta: Alcance y Asociaciones Esta guía presenta algunos conceptos básicos y ejemplos para entender las diferencias entre alcance estático y dinámico, así como entre asociación supercial y profunda. Nota: Es importante recordar que esta guía es un complemento, cuyo objetivo es ayudar al entendimiento de estos conceptos y su aplicación en la práctica. No debe considerarse un reemplazo para la bibliografía ocial del curso. 1. Preliminares: Nombres y Asociaciones Recordemos que un nombre, en el contexto de lenguajes de programación, es cualquier ca- dena de caracteres cuyo objetivo es representar algo más. Por ejemplo: identicadores, palabras claves e incluso operadores. Una asociación es el lazo que relaciona dichos nombres con aquello que representa. Estas asociaciones pueden ser: identicadores a valores (incluyendo sus tipos, direcciones de memoria, etc.), palabras claves y operadores a sus semánticas (comportamiento esperado), tipos a sus representaciones concretas de bajo nivel, etc. El momento de asociación es aquel en el que una determinada asociación es denida. Esto es, el momento en que un nombre es efectivamente asociado con su signicado. Los momentos de asociación se pueden agrupar por etapas distintivas, presentadas a continuación: Asociación temprana/estática Asociación tardía/dinámica Denición del lenguaje Carga Implementación del traductor o intérprete Ejecución Programación Compilación (incluyendo preprocesamientos) Enlace Cuadro 1: Clasicación de momentos de asociación. Es importante notar que la separación aparente entre momentos de asociación es difusa, más aún su clasicación como temprana o tardía. Algunos lenguajes permiten hacer compilación JIT (just in time), que permite compilar código solamente cuando es necesario. Esta compilación JIT hace que muchas asociaciones que se hacen a tiempo de compilación se hagan de forma dinámica. Así mismo, algunos lenguajes implementan optimizaciones de código donde expresiones constantes son evaluadas antes de comenzar la ejecución del programa. Esta optimización hace que algunas asociaciones que corresponden a tiempo de ejecución se hagan de forma estática. El tiempo de vida de una asociación es un concepto dinámico, el cual dene los períodos de tiempo en los que una determinada asociación para un nombre está activa. Por ejemplo, el tiempo de vida de una constante global de compilación es la de todo el programa y el tiempo de vida de una constante global de elaboración es desde el momento en que le es asignado un valor, hasta la terminación del programa. 1 2. Alcance El alcance de una asociación es la porción léxica (en el código) de un programa, donde la asociación en cuestión está activa. En particular, una asociación cuyo alcance es importante es la de identicadores con variables (o constantes). Una instrucción de la forma int x = 3; declara una variable, de tipo entero y con el valor 3. Tanto el tipo como el valor están asociados ahora al nombre x. Sin embargo, es mucho más util considerar que al identicador se ha asociado una variable, que a su vez tiene asociado un tipo y un valor. De esta manera, posteriores asignaciones a x no alteran la asociación, sino solamente la variable que está asociada. Algunos lenguajes de programación permiten que variables locales escondan asociaciones, segmentando el alcance de las mismas. La gura 1 muestra un ejemplo de cómo la primera asociación de x (verde claro) puede ser escondida por la segunda (verde oscuro). Figura 1: Ejemplo de segmentación de alcance. El programa mostrado imprimiría: 3 4 3. Pregunta: ¾Si la declaración interior se reemplazara por sólo una asignación, qué imprimiría entonces? Consideremos ahora el programa presentado en la gura 2 y para el mismo intentemos predecir lo que imprime. Figura 2: Programa de ejemplo. La respuesta es... ½Depende! Lo más intuitivo sería suponer que imprime 3, ya que es el valor de la variable global el procedimiento p2 x y no introduce nuevas asociaciones locales. A este comportamiento, donde el alcance viene dado por la disposición del código, se le conoce como alcance estático. Sin embargo se puede plantear que la asociación activa sea aquella que haya sido más recientemente creada y no 2 destruida. En ese caso, la asociación activa sería la de la se le conoce como alcance dinámico. Alcance estático: x declarada en p1. A este comportamiento Se basa en la disposición del código. El programa de la gura 2 imprimiría 3. Alcance dinámico: Se basa en la ejecución del código. El programa de la gura 2 imprimiría 4. Pregunta: ¾Qué ventajas y desventajas puede traer a un programador contar con un lenguaje de alcance estático o dinámico? Si se permite la declaración de subrutinas anidadas y pasaje de subrutinas como parámetros, los ejemplos puede ser mucho más oscuros. Consideremos ahora el programa en la gura 3: Figura 3: Programa de ejemplo con subrutinas anidadas. ¾Que imprime este programa? 3. Clausuras y asociaciones Aún no contamos con las herramientas necesarias para responder que imprime el programa de la gura 3, para ello debemos introducir el concepto de clausura. Una clausura no es más que el contexto nolocal que necesita un procedimiento para poder ejecutarse. En el caso del programa p2 utiliza una variable y, que no es parte de sus variables p2! Una clausura para este procedimiento consistiría en un anterior, vemos que el procedimiento locales ni parámetros. ½Es externa a apuntador a esta variable La clausura para p2 y, la cual será usada al momento de invocarse. podría hacerse en uno de dos momentos: El momento en que la subrutina es pasada como argumento por primera vez. A esta estrategia se le conoce como asociación profunda. Bajo esta estrategia, el programa de la gura 3 imprimiría 4. ¾Por qué no 8? 3 El momento en que la subrutina es nalmente invocada. A esta estrategia se le conoce como asociación supercial. Bajo esta estrategia, el programa de la gura 3 imprimiría 2. En situaciones en el que el tipo de asociación (supercial o profunda) es relevante, el alcance estático puede ser dependiente de la ejecución. La misma gura 3 presenta un ejemplo. Aún con alcance estático, el tipo de asociación determinó la instancia de la variable autores preeren llamar a este tipo de alcance léxico, en vez de estático. y. Por esto, muchos Pregunta: ¾Un mismo programa puede arrojar cuatro resultados diferentes, al considerar las combinaciones de alcance estático/dinámico y asociación profunda/supercial? De ser así, escriba tal programa. 4. El camino del bien A continuación les propongo lo que considero el camino del bien para resolver problemas que traten de alcance y asociaciones: Dibujar una pila, donde inicialmente solo están empiladas las variables globales. Cada vez que se haga una llamada a un procedimiento, empilar sus argumentos. • En el caso en que la asociación sea profunda, para cada procedimiento pasado como argumento se construye una clausura (tabla de símbolos externa) donde cada casilla tiene el nombre de la variable y una echa hacia la casilla en la pila que contiene su información. • En el caso en que la asociación sea supercial y el procedimiento invocado sea una variable, se construye una clausura para el mismo. Al pasar a dicho procedimiento, hacer explícito el cambio en la pila dibujada e incluir una echa al último bloque presente en la pila, que sea inmediatamente externo a él, en término léxicos. Cada nueva declaración de variable la empila junto con su valor. Las declaraciones de procedimientos internos son ignoradas. Al buscar valores de variables se hace buscando el más reciente en la pila si se está usando alcance dinámico, o el más reciente siguiendo la cadena de apuntadores a bloques léxicos, construida anteriormente si se está usando alcance estático. Estas instrucciones serán practicadas en clase (o en un video, en su defecto). Sin embargo, les adelanto la gura 4 como un primer ejemplo de esto. 4 Figura 4: Ejemplo del camino del bien. El programa utilizado fue sacado del 1er examen de EneroMarzo, 2012. La corrida corresponde a alcance estático y asociación profunda. La pila está construida hasta el momento en que se ejecuta nalmente el procedimiento 5. Q. Ejericios sugeridos Casi todos los primeros exámenes de la materia, como se ha dado durante los últimos años por el prof. Ernesto HernandezNovich y mi persona, tienen una o más preguntas sobre ejecución de programas con diferentes tipos de alcances y asociaciones. Les recomiendo buscen esos parciales e intenten resolverlos. Pueden escribirme si tienen cualquier duda al respecto. Ricardo Monascal / Febrero 2014 5