Está en la página 1de 121

LENGUAJES DE

PROGRAMACIÓN
Javier Martín
Centro Asociado de Móstoles
UNED
1

Introducción

JAVIER MARTIN (jmartin@escet.urjc.es)
 TUTORIAS:

JUEVES de 5 a 7

PLAN DE TRABAJO
 Exposición

de los temas y mediante transparencia,
abundando en los puntos más importantes.
 Resolución de dudas
 Propuesta y resolución de ejercicios y problemas

2

Unidad Didáctica 0: “Introducción”


Tema 1:
“El estudio de los lenguajes de programación”

3

4 .  Facilitar el diseño de un nuevo lenguaje.¿Porqué estudiar lenguajes de programación?  La pregunta es ¿cuál es la ventaja de estudiar una variedad de lenguajes diferentes que es poco probable que uno llegue a utilizar?:  Mejorar la habilidad para desarrollar algoritmos eficaces.  Mejorar el uso del lenguaje de programación disponible.  Hacer posible una mejor elección del lenguaje de programación.  Acrecentar el propio vocabulario con construcciones útiles sobre programación.  Facilitar el aprendizaje de un nuevo lenguaje.

Breve historia de los lenguajes de programación:  Desarrollo de los primeros lenguajes:  Lenguajes basados en el cálculo numérico (Ejemplo: FORTRAN).  Lenguajes para negocios (Ejemplo: COBOL).  Lenguajes para Inteligencia Artificial (Ejemplo: LISP). 5 .  Lenguajes para sistemas (Ejemplo: C).

Evolución de los Lenguajes de Programación Declarativos 6 .

Evolución de los Lenguajes de Programación Orientados a Objetos e Imperativos 7 .

Métodos de programación.  Surge la necesidad de trasladar programas de unos sistemas a otros. A mediados de los años sesenta la programación cambia: Las máquinas son menos costosas y aumentan los costos de programación.  El mantenimiento del producto consume mayores recursos de cómputo. Estandarización. 8 . Métodos de implementación. Estudios teóricos.   Los lenguajes de programación evolucionan o dejan de usarse. Influencias que obligan a la revisión del los lenguajes:       Capacidad de las computadoras.  La tarea del lenguaje de alto nivel es la de facilitar el desarrollo de programas correctos para resolver problemas en alguna área de aplicación dada.El papel de los lenguajes de programación  Inicialmente los lenguajes se proyectaban para ejecutar programas con eficiencia. Aplicaciones: Los requerimientos de nuevas áreas de aplicación afectan los diseños de nuevos lenguajes y las revisiones y ampliaciones de los más antiguos.

Costo de ejecución del programa. Ortogonalidad: Capacidad para combinar varias características de un lenguaje en todas las combinaciones posibles. Costo de mantenimiento de los programas: costo total del ciclo de vida. 4. 2. Portabilidad de programas Costo de uso:     1. y más tarde entender y modificar. Facilidad para verificar programas: La sencillez de la estructura semántica y sintáctica ayuda a simplificar la verificación de programas. 9 . Entorno de programación: Facilita el trabajo con un lenguaje técnicamente débil en comparación con un lenguaje más fuerte con poco apoyo externo. prueba y uso de programas. 3. por a prueba. Naturalidad para la aplicación: La sintaxis del programa debe permitir que la estructura del programa refleje la estructura lógica subyacente. Costo de traducción de programas. sencillez y unidad (legibilidad): La sintaxis del lenguaje afecta la facilidad con la que un programa se puede escribir. Apoyo para la abstracción: Una parte importante de la tarea del programador es proyectar las abstracciones adecuadas para la solución del problema y luego implementar esas abstracciones empleando las capacidades más primitivas que provee el lenguaje de programación mismo.Atributos de un buen lenguaje         Claridad. Costo de creación. de manera que todas ellas tengan significado.

Edición: Los sistemas de procesamiento de texto tienen su propia sintaxis para mandatos de entrada y archivos de salida.  De sistemas (ALGOL. casi toda la programación se podía dividir en cuatro modelos básicos de programación: De procesamiento de negocios (COBOL). Científicos (FORTRAN 90). Durante la década de 1960. ha aumentado la necesidad de contar con lenguajes para tiempo real. JOVIAL. PostScript se puede compilar por medir de un procesador adecuado. etc. La situación actual tiene más dominios de aplicación:      De procesamiento de negocios (COBOL). etc. Estos guiones se pueden invocar siempre que ocurren ciertas condiciones habilitadoras. 10 .  De Inteligencia Artificial (LISP).bat). De proceso: Dentro de UNIX. Éste suele ser la impresora láser que se utiliza para imprimir el documento.): Para construir sistemas operativos.. Dominios de aplicación Aplicaciones de los años sesenta. El traductor TEX produce un programa en el lenguaje PostScript de descripción de páginas. De sistemas: Con el advenimiento de los microprocesadores baratos que gobiernan automóviles. hornos de microondas.   Aplicaciones de los años noventa. el lenguaje de comandos de usuario se conoce como shell y a los programas se les llama guiones de shell (parecidos a los archivos .  Científicos (FORTRAN).

2. etc. Ejemplo: ANSI. Estándares de consenso (DE FACTO): Se trata de documentos elaborados por organizaciones con base en un acuerdo entre los participantes pertinentes..Estandarización de los lenguajes  Los estándares son en general de dos clases:    1. se somete a votación por parte de un bloque más grande de individuos interesados. IEEE. El organismo normativo organiza un grupo de trabajo de voluntarios para desarrollar esa norma. Los desacuerdos se resuelven y se produce el estándar del lenguaje. 11 . Método principal para asegurar la uniformidad entre varias implementaciones de un lenguaje. Proceso en el desarrollo de normas: Un grupo decide que un lenguaje requiere una definición estándar. ISO. Estándares patentados (DE PACTO): Son las definiciones elaboradas por la compañía que desarrollo el lenguaje y que es su propietaria. Cuando el grupo de trabajo llega a un acuerdo sobre su norma.

Uso de estándares en forma eficaz

Es necesario ocuparse de tres cuestiones:

Oportunidad (¿Cuándo estandarizar un lenguaje?): Lo deseable sería
estandarizar un lenguaje lo suficientemente pronto para que exista suficiente
experiencia en el uso del lenguaje, pero no demasiado tarde, para no alentar
muchas implementaciones incompatibles.
Conformidad (¿Qué significa que un programa se adhiere a un estándar y
que un compilador compila un estándar?): Si existe un estándar para un
lenguaje, se suele hablar de conformidad con respecto a ese estándar. Un
programa es conforme si sólo utiliza características definidas en el estándar.
Un compilador conformable es uno que, cuando se le da un programa
conforme, produce un programa ejecutable que genera la salida correcta.
Obsolescencia (¿Cuándo envejece un estándar y cómo se modifica?): Los
estándares se tienen que revisar cada 5 años y ya sea renovarse o
descartarse. Casi todos los estándares requieren compatibilidad hacia atrás;
El nuevo estándar debe incluir versiones más antiguas del lenguaje. Esto
tiene el problema de que el lenguaje se puede hacer difícil de manejar a
causa de las numerosas construcciones obsoletas.

Una característica es obsolescente si es candidata a ser descartada en la
próxima versión del estándar.
Una característica desaprobada se puede volver obsolescente en el
próximo estándar, por lo cual puede ser descartada después de dos
revisiones.
12

Efectos de los entornos sobre
los lenguajes

Cuatro clases generales de entornos objetivo
cubre casi todas las aplicaciones de
programación:
 de

procesamiento por lotes,
 interactivo,
 de sistema empotrado, y
 de programación (entorno interactivo).

Cada uno plantea distintos requerimientos
sobre los lenguajes adaptados a esos
entornos.
13

Entornos de procesamiento por
lotes

El más simple entorno operativo se compone sólo de
archivos externos de datos. Un programa toma un cierto
conjunto de archivos de datos como entrada, procesa los
datos y produce un conjunto de archivos de datos de salida.
El nombre de procesamiento por lotes viene porque los
datos de entrada se reúnen en “lotes” de archivos y son
procesados en lotes por programas.

Los archivos constituyen la base para casi toda la estructura de E/S.
Un error que termine la ejecución del programa es aceptable aunque
costoso. No es posible la ayuda externa por parte del usuario para
manejar o corregir errores de inmediato.
Carencia de restricciones de regulación de tiempo. No hay recursos
para monitorear o afectar directamente la velocidad de ejecución del
programa.
14

). juegos.     Las características de E/S interactivas son diferentes de las operaciones ordinarias con archivos. El programa debe ser capaz de gestionar el manejo de errores. hojas de cálculo.Entornos interactivos  El programa interactúa durante su ejecución directa con un usuario en una consola de visualización. etc. La terminación del programa como respuesta aun error no es ordinariamente aceptable (a diferencia del procesamiento por lotes). Los programas interactivos deben utilizar con frecuencia algún concepto de restricciones de tiempo. enviando alternativamente salidas hacia ésta y recibiendo entradas desde el teclado o ratón (procesadores de texto. El concepto de programa principal suele estar ausente. el programa se compone de un conjunto de subprogramas y el usuario introduce el “programa principal como una serie de comandos en el terminal. En su lugar. 15 .

16 . La seguridad de funcionamiento y corrección son atributos principales. donde la respuesta las entradas debe producirse en intervalos de tiempo restringidos. se ejecutan por lo común de forma simultánea e indefinida. Cada programa debe estar preparado para manejar todos los errores en forma interna. una aeronave. se conoce con el nombre de sistema de computadora incrustado. etc. Operan en tiempo real. adoptando acciones apropiadas para recuperarse y continuar.      Suelen operar sin un sistema operativo subyacente y sin archivos de entorno y dispositivos de E/S usuales. El programa debe interactuar directamente con la máquina. El fallo de una aplicación empotrada puede poner en peligro la vida. Una vez iniciadas las tareas.. La interrupción del programa no es aceptable y no hay un usuario en el entorno que pueda proporcionar la corrección interactiva del error. compuesto por más de una computadora. El manejo de errores tiene gran importancia. Suele ser un sistema distribuido.Entornos de sistemas incrustados (empotrados)  Un sistema de computadora que se usa para controlar parte de un sistema más grande como una planta industrial.

depurador. Asertos: expresan relaciones que deben cumplirse entre los valores de las variables en ese punto del programa. Características para rastreo de ejecución. 17 . 1. durante el ensamblado del programa final completo. 3. Todo nombre compartido debe ser único. orden y tipo de parámetros. que varios subprogramas y otras unidades de programa tienen nombres (de variables) iguales. Características que ayudan a poner a prueba y depurar programas. es encontrar. 3. Se deben usar convenciones para la asignación de nombres desde un principio.Entornos de programación   Es el entorno en el cual los programas se crean y se ponen a prueba. Métodos para evitar este problema: 1. etc. generadores de datos de prueba. Puntos de interrupción. para ocultar nombre. 2. Los nombres se pueden conocer agregando explícitamente sus definiciones desde una biblioteca externa (herencia en POO). La definición de un tipo de datos (para la declaración local de variables). la misma se interrumpe y el control se traslada al programador en un terminal. Cuando se alcanza un punto de interrupción durante la ejecución del programa.) de apoyo y un lenguaje para invocarlas.  La especificación del número. La declaración de tipo de datos. Consiste en un conjunto de herramientas (editor. en el lenguaje. reglas de ámbito. 2. Definir. Al compilar por separado cada subprograma el compilador necesita información de:     Un problema común. verificador.

Marcos de ambiente  Un ambiente de apoyo consiste en servicios de infraestructura que se conocen como marco de ambiente. 18 . Los programas se escriben de modo que utilicen estos servicios. seguridad y servicios de comunicación. Este marco suministra servicios como un depósito de datos. interfaz gráfica de usuario.

como sería la máquina de Turing (el primer ejemplo de una MV). son capas de software que juegan un papel relevante tanto en el funcionamiento de los lenguajes compilados como interpretados. 19 . una MV se puede definir sencillamente como una capa de abstracción que separa el funcionamiento de un ordenador de su hardware. y concretas o prácticas (a las que se quiere normalmente se hace referencia al hablar de MV). como se verá. Además. En esta sección se tratarán las MV concretas que. las MV se dividen en abstractas o teóricas.Máquinas virtuales  Aunque hay muchos rasgos que se podrían destacar como candidatos para formar parte de una definición del concepto de máquina virtual (a partir de ahora MV).

Introducción al concepto   Las MV se construyeron para simplificar el proceso del control del hardware de un ordenador porque extienden y enmascaran la funcionalidad del hardware a través de procedimientos y datos abstractos. Se pueden identificar dos tipos de MV concretas:  las que juegan un papel en la preparación de un programa para su ejecución (tiempo de compilación) y  las que permiten la ejecución de dicho programa. La figura muestra la diferencia entre los dos tipos: 20 .

21 .El papel de las máquinas virtuales en la compilación y la ejecución de un programa.

 •Las decisiones de implementación tomadas por los desarrolladores. presenta una visión de alto nivel de muchos tipos distintos de impresoras. por ejemplo. A la hora de implementar un lenguaje de programación.Introducción al concepto  Las MV suelen aparecer en una jerarquía.   PostScript es una MV que incluye el estado gráfico. las estructuras de datos y algoritmos utilizados en la ejecución de un programa (es decir. 22  . Las MV se distinguen entre sí según tres criterios: •La concepción de las MV que tiene el desarrollador basada en la definición del lenguaje. el estado del diccionario y.  •Las facilidades disponibles en el hardware del ordenador. la ruta actual. la sintaxis y semántica de cada estructura) definen las MV (implícitamente) para este lenguaje. Y las decisiones que toma el desarrollador afectan tanto a la traducción como a la ejecución de los programas escritos en este lenguaje. cada vez que invocamos el compilador de C+ +. Y dos ejemplos muy comunes del papel de una MV en la jerarquía de MV de ejecución son PostScript (que define una MV para una impresora) y MSDOS bajo MS Windows (que define una MV que permite que antiguos programas de DOS funcionen bajo Windows). aislando las características de las impresoras de las aplicaciones que las usan. aunque sea bastante complejo. Usamos la jerarquía de MV de compilación.

en caso de que vayan más allá que el modelo funcional de los compiladores ya disponibles como. 23 .  No tiene sentido repetir el proceso de diseño y desarrollo.   Un caso lo constituyen los compiladores C. Pentium IVdespués de Pentium III). habrá que modificar el compilador. En general. por ejemplo. no es nada común hacerlo hoy en día por varias razones. que es costoso. cuando ya se ha hecho lo mismo muchas veces antes para otros lenguajes para una máquina concreta. es el caso de Java.Introducción al concepto  Aunque se puede escribir un compilador para traducir (o compilar) un programa escrito en un lenguaje de alto nivel directamente al código máquina (en el sentido de no depender de ninguna otra pieza en el sistema para producirlo). Por lo tanto. hay varios lenguajes como C++ (al menos en las primeras versiones) cuyo “compilador” tradujo el código fuente de C++ a C para poder luego usar el compilador C estándar. sólo se suele rediseñar un compilador nuevo desde cero cuando los ingenieros del lenguaje están intentando alcanzar nuevos objetivos para ese lenguaje. que ya llevan mucho tiempo en funcionamiento y son muy eficientes y estables. dos de las cuales son: Cuando aparezca en el mercado el siguiente procesador (por ejemplo.

aquí se supone que es un proceso de compilación que usa C como código intermedio). también existe otro proceso. como lenguaje de alto nivel que se compila a un lenguaje tan cerca del nivel de máquina como sea posible. sino como parte de una jerarquía de MV. En primer lugar. como puede verse. compuesto por el código máquina de entrada y todos los subprogramas necesarios con direcciones de memoria contiguas. que tiene más que ver con el papel de las MV en el tiempo de ejecución que en el tiempo de compilación. El compilador C acepta este código como fuente y lo traduce a código ensamblador (una representación simbólica del código máquina). etc. el cargador de librerías acepta este código máquina como entrada y produce un programa simple ejecutable. Y por fin. por ejemplo. A continuación se va a ver el papel de las jerarquías de MV en el tiempo de compilación y de ejecución. Y en el futuro. El ensamblador traduce este código simbólico a un código máquina reubicable. En el caso de C++. El traductor convierte el código fuente C++ estándar a código fuente C. 24 . El pre-procesador acepta el código C++ como fuente y produce otra versión del mismo código C++ con algunas extensiones e incorporaciones resueltas. Además del proceso de compilación. la traducción completa de los programas de alto nivel (previa a su ejecución) en una forma que corre sobre la máquina.Jerarquías de máquinas virtuales   La realidad es que el desarrollador de un lenguaje suele implementar las MV (de compilación y/o ejecución) de su lenguaje en términos de otras MV ya existentes. es que una MV no suele existir aislada. se va a considerar el papel de la jerarquía de MV en el tiempo de compilación. que se llama interpretación. un programador de aplicaciones utilizará las MV implementadas por el desarrollador del lenguaje para producir programas que a su vez puedan servir como MV para otras aplicaciones. se puede ver que el proceso de compilación de un programa de C++ consiste en la interacción de la jerarquía de MV mostrada en la figura 2 (aunque puede haber diferencias entre compiladores de C++. La conclusión.

en vez de en código máquina (lenguajes intermedios).Jerarquías de máquinas virtuales   Además de los lenguajes compilados “completamente”. Y los programas que componen esta MV corren sobre el firmware. un conjunto de programas de microcódigo que controlan directamente el hardware del 25 ordenador. a su vez. . vamos a considerar el papel de la jerarquía de MV en el tiempo de ejecución. utilizan las funciones de la MV del sistema operativo implementadas en código máquina. Como se puede ver en él. lo que se podría llamar una aplicación Web (unas páginas Web con elementos interactivos incrustados) está escrita en HTML y funciona sobre una MV dada por el navegador Web. hay otros que son compilados “parcialmente” en el sentido de que terminan el proceso de compilación en un código (o lenguaje) intermedio. Éste corre sobre una MV compuesta por las librerías de tiempo de ejecución que encapsulan el funcionamiento de los procedimientos (o métodos) y datos de navegador Web que. Se puede ver un ejemplo en la figura 3. En segundo lugar. que a su vez está implementado en C o C++.

La diferencia es que una MV puede tener una interfaz hacia abajo. 26 .Jerarquías de máquinas virtuales   Las jerarquías del tipo mostrado en la figura tienen una estructura muy parecida a una jerarquía “usa”. una capa que define el funcionamiento en términos de los dispositivos. además de la interfaz hacia arriba. no de una implementación en concreto de esta capa (por lo tanto. que especifica los servicios que requiere de la capa inferior. donde cada capa usa la capa que está directamente debajo. donde hay una capa que define el funcionamiento independientemente de los dispositivos y. directamente debajo. las demás capas superiores son idénticas). Aquí X depende de la capa que depende de los dispositivos. Un ejemplo sería la jerarquía de MV que compone el sistema de ventanas X. pero sin especificar exactamente qué implementación de los servicios es necesario. hay versiones de X para muchos tipos de hardware donde la única diferencia es la implementación de la capa relacionada con los dispositivos.

entre el lenguaje de entrada (el nivel más alto) y el código ejecutado en la máquina (el nivel más bajo) tanto en el tiempo de compilación como en el de ejecución. 27 .Lenguajes intermedios  Un lenguaje intermedio se puede definir como una manera de representar procedimientos y estructuras de datos que sirva como entrada para una MV en alguna parte de su jerarquía.

Lenguajes intermedios  Un lenguaje intermedio se puede definir como una manera de representar procedimientos y estructuras de datos que sirva como entrada para una MV en alguna parte de su jerarquía. entre el lenguaje de entrada (el nivel más alto) y el código ejecutado en la máquina (el nivel más bajo) tanto en el tiempo de compilación como en el de ejecución. 28 .

es decir.Lenguajes intermedios  Para considerar el papel de los lenguajes intermedios y sus ventajas y desventajas. esta MV se construye a través de un conjunto de programas de código máquina que representa los algoritmos y estructuras de datos necesarios para la ejecución de las instrucciones del lenguaje de alto nivel. conviene destacar la diferencia entre la traducción de un lenguaje de alto nivel a código máquina anteriormente a su ejecución (su compilación) y su interpretación. la conversión de cada instrucción del lenguaje a código máquina y su ejecución. Hay ventajas y desventajas en cada manera de convertir los lenguajes de alto nivel a código máquina. una por una. Y típicamente. al ejecutar el programa. Este proceso se realiza a través de una MV de interpretación que simula un ordenador cuyo código máquina es el lenguaje de alto nivel que está siendo interpretado. que se pueden resumir así: 29 .

Lenguajes intermedios 30 .

que es una mezcla de los dos enfoques. esta técnica combina las ventajas y desventajas de los dos enfoques anteriores. como ya se ha visto. donde se compila el lenguaje de alto nivel a un lenguaje intermedio (más cerca de las estructuras presentes en el código máquina que las del código fuente) y luego se interpreta este lenguaje al ejecutar el programa. existe también lo que se llama la compilación parcial. 31 .Lenguajes intermedios   Estos dos casos representan los dos extremos porque. Como puede imaginarse. Un ejemplo de esta combinación existe en el lenguaje de programación Java y su entorno.

Java Runtime o JRE). como lenguaje intermedio. la interpretaría para su ejecución. este bytecode podría correr en cualquier hardware donde haya una versión del JRE disponible. Java empezó con la idea de liberar al programador de las dificultades de portar su aplicación a nuevas plataformas lo cual. Como este bytecode está más cerca del nivel de máquina que de un lenguaje de alto nivel. si el programa está muy vinculado a algún aspecto del sistema operativo donde fue escrito. Y a la hora de correr el programa. Se compilará el código fuente de Java a un código byte (bytecode) antes de ejecutarlo. aunque más despacio que los programas previamente compilados al código máquina. sería el lenguaje de entrada para una MV. podría ser muy difícil. este código. Por lo tanto.Lenguajes intermedios    Entre otras cosas. que con un conjunto de librerías (el entorno de ejecución de Java. los programas correrán más rápidamente que los programas completamente interpretados. 32 .

en el sentido de que supone menos trabajo a la hora de ejecutarlo y.Lenguajes intermedios  Como se puede ver en la figura 1. 33 . tanto los programas compilados parcialmente a un lenguaje intermedio (como Java) como los programas escritos en lenguajes de alto nivel que se interpretan (como Lisp) requieren una MV para interpretar el programa. por lo tanto. los programas corren más rápidamente que los puramente interpretados. La principal ventaja del lenguaje intermedio en este caso es su proximidad al nivel del código máquina.

Lenguajes intermedios  Además del papel de los lenguajes intermedios en la compilación parcial. sólo tendrá que implementar una MV para convertir el código fuente de su lenguaje a C. Si el autor de un nuevo lenguaje decide utilizar C. por ejemplo. 34 . Como ejemplo se puede considerar C como lenguaje intermedio para un lenguaje compilado nuevo. se puede destacar su papel en la compilación estándar. ahorrando mucho trabajo. como su lenguaje intermedio.

Lenguajes intermedios  Las ventajas de utilizar un lenguaje tan establecido como C como lenguaje intermedio son:  •La facilidad de portar el lenguaje a una nueva máquina (sólo hay que tener un compilador C disponible allí). características de memoria o rendimiento – se pueden añadir librerías C customizadas sin grandes problemas). 35 .  •Las posibilidades disponibles para mapear estructuras intermedias del nuevo lenguaje a estructuras de datos de C.  •La generación de código máquina es una tarea muy compleja que requiere un conocimiento profundo de la arquitectura de la máquina en cuestión – y de cada máquina en que se quiere una versión del lenguaje.  •La facilidad de modificar algún rasgo del comportamiento del lenguaje en alguna máquina en concreto (por ejemplo.

 •Habrá ocasiones en las que no exista una buena traducción entre una estructura en el nuevo lenguaje y las estructuras de datos en C.  •Las características de rendimiento y eficiencia del lenguaje están determinadas por el  compilador C. entre otras cosas.Lenguajes intermedios  Y las desventajas son:  •La depuración es muy difícil porque. los errores que ocurren en el código C no son muy fáciles de localizar en lo que ha escrito el programador originalmente en el nuevo lenguaje. por ejemplo. 36 . por lo que habrá una pérdida de eficiencia en el programa resultante (como. ocurre en la mayoría de las ocasiones en que se compilan estructuras de Prolog a C – sólo se puede expresar iteración en Prolog utilizando recursión).

La máquina virtual de Java como ejemplo de una MV   La MV de Java es una máquina de pila. a un punto flotante o a una referencia a objeto (puntero). El contenido ejecutable de un archivo de bytecodes contiene un vector de instrucciones bytecode para cada método. Para puntos flotantes dobles y enteros largos se utilizan dos huecos de la pila. Las instrucciones interpretadas por ella manipulan datos almacenados como elementos en una pila. Los bytecodes son instrucciones para la MV. Cada variable local o elemento de la pila es una palabra que corresponde a un entero de 32 bits. que tiene algunos registros de variables locales y una pila para la evaluación de expresiones. 37 . Las primeras variables locales son inicializadas con los parámetros actuales.

Sin embargo. El tipo de datos podría ser “no asignado”.La máquina virtual de Java como ejemplo de una MV   Los huecos de la pila no están relacionados con un tipo de datos. en cualquier punto del programa. Aún más. con lo cual no se permite leer el valor del hueco. el mismo hueco podría contener una referencia a un objeto. 38 . en algún punto un hueco podría contener un valor entero y en otro. el contenido de cada hueco está asociado con un único tipo de datos que puede ser determinado usando un flujo estático de datos. Estas restricciones son parte del modelo de seguridad de Java y se ven reforzadas por el verificador de bytecodes. es decir. no se puede almacenar un entero en un hueco y luego recuperarlo reinterpretándolo como si fuera una referencia a un objeto.

Se han señalado muchas posibilidades para mejorar el rendimiento de los intérpretes. y la representación compilada de los métodos que corresponden al programa es ejecutada al efectuar una llamada. Una muy común hoy en día es incluir un compilador relativamente simple en el tiempo de ejecución de la MV. Just In Time). Es decir. en vez de interpretar los bytecodes del programa una y otra vez.La máquina virtual de Java como ejemplo de una MV   El código interpretado es generalmente más lento que un programa escrito en un lenguaje compilado. 39 . se compilan una sola vez “al instante” en el interior de la MV. y Java no es distinto en este aspecto. Esto es conocido como un compilador al instante (o JIT.

Unidad Didáctica 1: “Sintaxis y Semántica de los Lenguajes de Programación”   Tema 2: “Sintaxis formal de los lenguajes de programación” 40 .

Ver Sintaxis y Semántica del resumen en  Problema de traducción de lenguajes (Capitulo 2)  41 .

Unidad Didáctica 2: “Paradigmas y lenguajes ”   Tema 4: “Descripción de los paradigmas más representativos ” 42 .

Un paradigma de programación es un modelo de programación que engloba a ciertos lenguajes que comparten:   Elementos estructurales: ¿con qué se confeccionan los programas? Elementos metodológicos: ¿cómo se confecciona un programa? 43 .PARADIGMAS DE PROGRAMACIÓN  La clasificación de los lenguajes atendiendo a sus características intrínsecas conduce a los llamados paradigmas de programación.

Desde este punto de vista un programa es una secuencia de acciones (instrucciones) que se realizan en un cierto orden determinado por el flujo del programa. Como un ejemplo ilustrativo veamos el aspecto de un programa en lenguaje Pascal que calcula el factorial de un número positivo x: 44 . Las estructuras para el control son generalmente sentencias condicionales y bucles.Programación Imperativa o Procedural: FORTRAN   Es la primera que se desarrolla porque va determinando las operaciones que hay que realizar sobre una máquina ideal de Von Neumann.

 Desarrollado por IBM para el IBM 704.FORTRAN.  Definición estándar del lenguaje en el 66.  Estaba orientado a la eficiencia en la ejecución. Historia Primer lenguaje de alto nivel (1957).  Otras versiones:   FORTRAN 77  FORTRAN 90 45 .

 2) CALL PRINTIT STOP END SUBROUTINE PRINTIT PRINT *.’Hola Mundo’ RETURN END 46 .FORTRAN. Ejemplo PROGRAM TRIVIAL INTEGER I I=2 IF(I .GE.

Sólo dos ámbitos para las variables: local y global 47 .FORTRAN. reales. y no requiere sentencias GOTO. Características Tipos de datos:  Numéricos (enteros.  Booleanos (logical)  Arreglos  Cadenas de caracteres  Archivos   FORTRAN 90 ya es estructurado. complejos y doble precisión).

Ejemplo anotado 48 .

En FORTRAN 90 se declaran INTEGER. Para memoria dinámica ALLOCATE y DEALLOCATE 49 . Declaración explicita de variables. Punteros: en los primeros FORTRAN no hay punteros y todas las variables se almacenan en memoria estática. (se modifica con IMPLICIT).FORTRAN. el resto reales. POINTER::P. Enteras (I-N). Los blancos son significativos. Los nombre de variables tienen de 6 a 31 caracteres máximo y deben comenzar por una letra. Objetos de datos Variables y constantes      FORTRAN no es sensible a mayúsculas y minúsculas.

. el primer carácter es el 1.Y/3. pueden tener hasta 7 dimensiones y se guardan por colummnas.. Se usa COMMON para datos compartidos y EQUIVALENCE cuando almacenamos una variable con dos posibles tipos en la misma posición de memoria (como union en C).K/20/ Tipos definidos por el usuario. Objetos de datos Tipos de datos estructurados  Arrays. Se usa DATA para inicializar datos estáticos. REAL M(20).0/. END TYPE <nombre> 50 .1416/. el operador // permite concatenar cadenas.FORTRAN.N(-5:5)  DIMENSION I(20. con TYPE <nombre>.   Almacenamiento de datos.   CHARACTER S*10. T*25 DATA X/1.20) (tipo por nomenclatura implícita)   Cadenas de caracteres.

. DO..   Control de subprogramas.. CONTINUE. cuando se hace entre cadenas hay ajuste de tamaño con blancos o truncamiento. 51 .  Condicional.. END SELECT  Iteración. Control de secuencia EL conjunto de estructuras de control es limitado:  Expresiones.. Construcciones propensas a error: GOTO.END DO  Nulo. Para selección múltiple SELECT CASE <expr> CASE. se usa solo para la etiqueta... prioridad de operadores  Enunciados  Asignación.. Permite IF <cond> ELSE IF..FORTRAN.. CALL invoca al subprograma y RETURN devuelve un valor al programa llamante...CASE DEFAULT.

INQUIRE (propiedades o estado del archivo) REWIND y ENDFILE (para ubicar el puntero del fichero). CLASE. WRITE. 52 . PRINT. Entrada y Salida  Tipos de archivos:  Secuenciales  De   acceso directo Comandos: READ.FORTRAN. OPEN . Para el tratamiento de excepciones en las sentencias READ/WRITE se puede introducir la posición de la rutina de dicho tratamiento (ERR=90).

 Subroutine.  Las variables son locales o globales (COMMON)  Recursividad: RECURSIVE FUNCTION FACTORIAL(X)  Parámetros de subprograma.FORTRAN. Subprogramas  Hay tres tipos de subprogramas:  Function. Paso por referencia.   FN(X. permite calcular una sola expresión aritmética o lógica.  Función de enunciado. lógico o cadena de caracteres.Y)=SIN(X)**2-COS(Y)**2 Gestión de almacenamiento. devuelven un solo valor de tipo numérico. 53 . devuelve valores a través de variables no locales COMMON.

Evaluación del lenguaje   La abstracción es posible mediante los subprogramas y el uso de variables COMMON. aunque su uso es propenso a errores.  El aspecto de los programas sigue siendo de procesamiento por lotes 54 . pues se ha transformado en un lenguaje estructurado. FORTRAN sigue siendo utilizado en el ámbito científico y es muy eficiente realizando cálculos.  En FORTRAN 90 se incluye la recursividad y la memoria dinámica.  La estructura del programa suele ser dificil de entender. ni el GOTO.Abstracción y encapsulamiento FORTRAN.  Las etiquetas de las sentencias ya no son necesarias.

C es distribuido con Unix y muy usado en las universidades.  Multiuso (inicialmente para sistemas)  Sintaxis compacta  Historia  60 Thompson desarrolla en Bell Multics. ANSI comienza a desarrollar un estándar 55 .Programación Imperativa o Procedural: C  Desarrollado por Ritchie y Thompson en el 72. se comienza a desarrollar C  82. se crea un lenguaje llamado B. el proyecto UNIX avanza y el lenguaje B se queda pequeño.  70.

estos enunciados no forman parte del lenguaje C y son preprocesados antes de la compilación.Perspectiva del lenguaje C  La programación en C se compone de:  El lenguaje C.  Las bibliotecas de C. con un limitado nº de estructuras de control.  Los supuestos de interfaz C (.h). lor archivos “header” informan al usuario de las funciones incluidad en una biblioteca. Archivos obj o lib conteniendo la implementación de 56 las funciones. .  El preprocesador de C (#). No hay primitivas si no se usan las librerías.

Ejemplo anotado 57 .

 No hay booleanos. short.Objetos de datos  Tipos de datos primitivos  Los nombres de variables no pueden comenzar con dígito. Struct { }. Sensible a may-min. long). enumerados (enum) o float. comienzan en 0 y se guardan por filas.  Union. pero todos los componentes ocupan la misma memoria. 58 .  Los datos son enteros (char. Los punteros se declaran con el tipo seguido de ‘*’.  Tipos definidos por el usuario.  Tipos de datos estructurados  Arrays. es una definición de tipo si tácticamente con un struct.

Representación de almacenamiento Los tipos de C emplean básicamente la representación hardware de sus datos.  Una variable de tipo array es también el puntero al primer elemento del array que comienza con el índice 0.  Es posible inicializar cualquier variable declarada estáticamente.  59 .

. Pueden ser bloques de sentencias entre llaves... continue..  Coerciones. pueden ser forzadas haciendo una cast unaria antes de un valor. if.. return.} Iterativos: while.. Condicinal múltiple..Se emplea notación infija... for.. goto. #ifdef..   Enunciados. do .. están en stdio..Control de secuencia  Expresiones..case. De preprocesador: #define.then.{case..h.       A + (int)b Condicional. #include. 60 ..default.... #if.#else C no tiene enunciados E/S..#undef. switch. Transferencia del control: brak..else.

extern int i. k. 61 . que la invoca cuando es llamada. Cada función tiene asociado un registro de activación.Subprogramas y Gestión de almacenamiento     main() es la función de entrada al programa principal. para que sea vistas por otros módulos. No hay anidamiento de funciones. Para simular paso por referencia hay que pasar el puntero “por valor”. j. por lo que las variables son globales o locales. Las globales deben ser declaradas por extern. Las funciones de C sólo toman argumentos por valor.

tambien se accederá a todos sus componentes. de manera que si se tiene acceso a un struct. pero no implementa el ocultamiento de la información.Abstracción y encapsulamiento El lenguaje da facilidades para la definición de tipos.  62 .  El uso de bibliotecas con interfaces header también permite la abstracción.

63 .Evaluación del lenguaje  C es muy potente y popular:  Flexible  Eficiente  Disponible (se distribuye con Unix)  Portatil  Pero C también permite una programación descuidada y propensa a errores.

Lenguajes funcionales: LISP 60.  La últimas versiones de LISP incluyen un recolector de basura  64 . lo que resta eficiencia a las ejecuciones. McCarthy en el MIT  Muy usado en IA  En LISP la recursión se emplea a menudo como estructura de control.

Hola Mundo en LISP 65 .

LISP es interpretado y usa una estructura de gestión de almacenamiento en montículo con recolección de basura como almacenamiento primario para datos y programas.’ Los parámetros de función van todos por valor o por referencia según la clasificación de la función. Los comentarios comienzan por ‘. Incluye primitivas para su manipulación.Perspectiva del lenguaje   Interactivo (usualmente) Los datos en LISP son muy restringidos:       Átomos literales (símbolos) Átomos numéricos La estructura de datos básica es la lista. 66 .

Ejemplo anotado 67 .

En los datos estructurados (listas) se tienen sólo punteros a primero y a siguiente. Tienen asociado un puntero al primer elemento (car) y otro al elemento siguiente (cdr). Para la asignación se utiliza setq(x val). No se distinguen may-min para identificadores  Tipos de datos estructurado: listas.  Representación y almacenamiento.   Cada descriptor de un objeto de datos proporciona tipo y atributos. 68 . accesible a través del puntero que almacena el nombre del átomo.Objetos de datos  Tipos de datos primitivos: átomos. Cada átomo tiene una lista de propiedades asociada. Una lista vacía apunta a nil.

/  Operaciones sobre listas: cons. *. list. La ejecución del programa consiste en la evaluación de las funciones contenidas en el mismo.  Definición de funciones: defun. print(). cdr.  Entrada y salida: open(). 69 .Control de secuencia    El traductor LISP es una función read() que toma el fuente del fichero y lo interpreta. define. get. equal. -. replace. null. car. Expresiones:  Condicional  Operaciones sobre átomos (en preorden): +. read().  Operaciones sobre propiedades: put.  Enunciados: prog() para ejecución secuencial.

Gestión de subprogramas

Tres clases de funciones:
 Función

interpretada, en forma de estructura
de listas. Primitivas eval y apply.
 Función compilada, compiladas en un bloque
de código máquina que puede ser ejecutado
por el interprete del hardware.
 Macro, se declara con define. Es simplemente
una función ordinaria en LISP. Puede ser
interpretada y compilada.
70

Gestión de almacenamiento

La memoria se estructura en forma de montículo, que
maneja unidades de una palabra de tamaño fijo usando
una lista de espacios libres y un recolector de basura.
Entorno de referencia:

Local, es el que se da en las listas, como asociaciones de átomos
relacionados de una determinada manera.
Global o común, se consigue mediante asociación de un átomo
con una propiedad del mismo que contiene un puntero al datos
referenciado. Se usa set y setq.

Paso de parámetros:

Transmisión por valor, consiste en evaluar las expresiones de una
lista de parámetros y transmitir los valores resultantes.
Transmisión por nombre, transmitir las expresiones de la lista de
parámetros sin evaluar, y dejar que la función llamada los evalue
usando eval. En funciones macro la transmisión por nombre es la
norma. Para funciones lambda se puede especificar la transmisión
por nombre usando nlambda, en lugar de lambda.
71

Funciones en LISP I

Funciones normales, son las que se suelen incluir en las
implementaciones de LISP (ver manual en cada caso).
Funciones de lista, para manipulación de listas:




car L, devuelve el primer elemento de L.
cdr L, devuelve la cola (lista - primero).
cons x y, devuelve uan lista formada por x e y.
list x y z, devuelve la lista (x y z).
quote x, no se evalúa x

Predicados








atom x, devuelve True si x es un átomo.
numberp x, devuelve True si x es un número
greaterp x y, devuelve True si x>y
lessp x y, devuelve True si x<y
null x, devuelve True si x es nulo
and x y, devuelve x and y
or x y, devuelve x or y
not x, devuelve not x
eq x y, devuelve True si x=y

72

-. termina LISP 73 . imprime el elemento x  open nombrearchivo. lee el archivo a memoria  print x. y /. *. lee del terminal un átomo  help. abre un archivo y devuelve una puntero al mismo  read.  Funciones de entrada y salida  load nombrearchivo.  rem x y. traza la función  bye. proporciona ayuda  trace. devuelve el módulo x/y (remainder).Funciones en LISP I  Funciones aritméticas:  +.

Características:  Herencia múltiple  Funciones genéricas  Metaclases y metaobjetos  Técnica de creación e inicialización de objetos que permite control del proceso por parte del usuario. no incluye características de abstracción de datos. 74 . en origen. CLOS fue una ampliación de LISP con orientación de objetos.Abstracción y encapsulamiento   LISP.

Evaluación del lenguaje LISP ha evolucionado durante más de 30 años y desarrollado para inteligencia artificial.  75 .  Las versiones compiladas son algo más eficientes. pero no es adecuado para aplicaciones convencionales.

en vez de dar el algoritmo para su resolución.Programación lógica: PROLOG  PROLOG está orientado a la resolución de problemas mediante el cálculo de predicados. La solución se obtiene mediante búsqueda aplicando la lógica de predicados. basado en:  Preguntas a la base de datos  Pruebas matemáticas  El programa PROLOG especifíca cómo debe ser la solución. 76 .

pero de forma muy limitada debido a la falta de aplicaciones en dicho lenguaje.  77 . cláusulas de Horn.Historia Coulmerauer (1970) desarrolló un lenguaje para hacer deducciones de texto  Se aplica un mecanismo de resolución sobre predicados especiales.  La difusión del lenguaje se produce en los 80. llamado unificación.

Hola mundo. en PROLOG 78 .

Comentarios entre /* */ 79 . es decir. las variables y las listas. PROLOG tiene una sintaxis y semántica simples. La ejecución del programa cargado en memoria consiste en realizar una pregunta de forma interactiva: el interprete generará por inferencia los resultados que se deducen a partir del contenido de la base de datos. Sólo busca relaciones entre los objetos creados.Perspectiva del lenguaje     El programa prolog se compone de unos hechos (datos) y un conjunto de reglas. relaciones entre objetos de la base de datos. que son sus estructuras básicas.

Ejemplo anotado 80 .

El alcance de una variable es la regla donde aparece. . representadas entre [ ]  Tipos definidos por el usuario.Objetos de datos  Tipos de datos primitivos: variables y constantes:  Enteros  Reales  Caracteres Los identificadores con minúscula representan hechos.  Tipos de datos estructurados:  Átomos: constantes y variables de cadena  Listas. los que van con mayúscula variables. Las reglas para definir relaciones pueden actuar como tipos de 81 usuario.

 82 . Para cada una de ellas se evaluará su corrección. La búsqueda se puede hacer más eficiente mediante la poda del árbol de búsqueda (corte).Representación de almacenamiento Las reglas y hechos son almacenadas en memoria como listas enlazadas.  La ejecución de prolog consiste en una búsqueda en profundidad de un árbol conteniendo todas las posibles soluciones.

Reglas. sucesión de términos que finalizan con un punto.  Enunciados      Hechos. relaciones que se expresan en una consulta. Entrada y salida. pero puede hacer más eficiente la búsqueda. Cortes. 83 . implicaiones que se expresan en una operación consult Preguntas. operaciones aritméticas y operadores relacionales. Not(). Esto puede impedir que se encuentren ciertas soluciones.Control de secuencia El orden de evaluación es secuencial  Expresiones. fuerza el retroceso en la búsqueda. nl y write. (!). Son tuplas con un nombre de predicado y unos argumentos.

todas las variables son locales a la regla en que están definidas. Modos pregunta. se introducen nuevas relaciones (hechos) en el almacenamiento dinámico de la base de datos. siempre fracasa See(nombrearchivo). activa la depuración del programa . lee las entradas de un archivo y las incorpora al conjunto de reglas. La unificación hace interaccionar nombres locales de una regla con los de otras reglas. la unificación proporciona el paso de parámetros entre reglas.Subprogramas y gestión de almacenamiento  PROLOG tiene dos modos:    Alcance de las variables:     Modo consulta. devuleve cierto si X es un átomo Var(X). Paso de parámetros. devuelve cierto si X es un entero 84 Trace. Ambiente local de referencia. salto de línea Atom(X). Funciones normales. devuelve cierto si X es una variable Integer(X). todos los datos son compartidos. Write(término) Tell(término). Ambiente común de referencia. van integradas en el lenguaje:            Consult(nommbrearchivo) Fail. cierra el archivo anterior Nl. se ejecuta un intérprete basado en pilas para evaluar las preguntas del usuario. reorienta la salida del write al archivo Told.

85 .Abstracción y encapsulamiento  PROLOG no proporciona estas capacidades.

e. Tratamiento del lenguaje natural. A pesar de que es posible desarrollar programas sin especificar el algoritmo de resolución a veces hay que echar mano de otro tipo de programación para hacer los programas más eficientes. y consulta de bases de datos. y a menudo se emplea el corte para limitar el espacio de búsqueda.Evaluación del lenguaje   PROLOG va bien para problemas de relaciones. p. 86 .

Unidad Didáctica 2: “Paradigmas y lenguajes ”   Tema 5: “El paradigma de la programación orientada a objetos (POO)” 87 .

PROG. ORIENTADA A OBJETO  Ver Apuntes sobre la POO 88 .

HERENCIA


Con frecuencia la información se pasa entre
componentes de programa de manera implícita,
a este traspaso de información le llamamos
herencia.
La herencia consiste en la recepción en un
componente de programa de propiedades o
características de otro componente de acuerdo
con la relación especial que existe entre ambos
componentes.
Las reglas de alcance de variables son una
forma de herencia.
La herencia múltiple se da cuando una clase
tienen varias superclases de las que hereda.
89

Clases derivadas

La herencia se implementa en los lenguajes orientados
a objetos a través de clases derivadas, que heredan
propiedades y métodos de sus superclases.
La visibilidad de los objetos heredados depende de la
forma en que se declaran:


PRIVATE
PUBLIC
PROTECTED

Implementación: En la clase derivada los nombre
derivados de la superclase se agregan al espacio.

Si en la definición hay una función constructora, hay que incluir
en la declaración una llamada a dicha función.
El objeto guarda la referencia de los apuntadores a todas las
propiedades y métodos, a esto se llama enfoque con base en
copia de la herencia (usado en C++).
90

Métodos

La herencia de métodos para crear objetos
nuevos proporciona un poder adicional que va
más allá del simple encapsulamiento.
En las clases derivadas, cuando se quiere
cambiar uno de los métodos hay dos
posibilidades:
 Redefinir

el método en la clase derivada
 Usar una función virtual, que se enlaza
dinámicamente en el momento de llamada del
subprograma.

91

Esto requiere que todos los objetos que requieren esta clase se definan de una subclase derivada. No se puede crear ningún objeto que tenga funciones virtuales nulas. También se llama herencia de incorporación. Las diferencia se define en una clase delta: Deltaclass ModPila {}  Class PilaNueva = class PilaElem + deltaclass ModPila La ventaja es que las clase delta se pueden adicionar a cualquier clase. del tipo:   Virtual void NombreDeTipo()=0.Clases abstractas   Se usa cuando la superclase define una especie de plantilla para las subclases. 92  . en la que solo se define la diferencia entre la clase base y la clase derivada. HERENCIA MIXIN. aunque no permite que se declaren objetos en esta definición.

Objetos y mensajes  El lenguaje Smalltalk presenta 3 características:  Definición de clase. Los métodos se pasan como mensajes a un objeto para llevar a cabo una acción. Se crean objetos específicos para cada definición de clase. Los mensajes de palabra clave se usan para hacer asignaciones de valor. principalmente.  Paso de mensajes. por ejemplo. El mensaje binario se usa. Tipos:    Un mensaje unario es un método sin parámetros. Define la estructura interna y los métodos que se pueden usar para crear y manipular objetos. para operadores aritméticos.  Ejemplarización de objetos. en un array:   X_Array new: 10 X at:3 put:42 93 .

y así sucesivamente.Herencia de clases Si se envía un mensaje a un objeto con un método que no está definido en su clase se pasa a la clase progenitora.  En los métodos de palabra clave el parámetro se nombra de forma explícita en la declaración del método  94 .

Individualización. Lo contrario es la agregación. fundamentalmente. es el proceso de crear ocurrencias de una clase (se trata de un proceso de copia). objetos similares se agrupan con otros para propósitos comunes. La abstracción y la herencia puede ser usada para impedir al programador ver el contenido de los objetos de datos que no convenga. Ejemplarización. Permite:     Especialización.Conceptos de abstracción   El encapsulamiento es un mecanismo divide y vencerás para proporcionar control sobre el programa en desarrollo. La herencia. permite separar una abstracción en sus componentes. Descomposición. es un mecanismo para pasar información entre objetos en clases relacionadas. para que los objetos derivados contengan caracterísiticas de otros objetos. Es lo contrario de agrupamiento. 95 .

POLIMORFISMO  El polimorfismo es la capacidad de un solo operador o nombre de subprograma para referirse a varias definiciones en función del contexto. de los tipos de daos de los argumentos y del resultado. 96 . es decir.

Unidad Didáctica 2: “Paradigmas y lenguajes ”   Tema 6: “La programación centrada en la red” 97 .

 Ver Apuntes sobre la PCR 98 .

declaraciones y control” 99 .Unidad Didáctica 3: “Mecanismos de los LP”   Tema 7: “Tipos.

son las que el programador usa de forma optativa.  Estructuras de control explícitas.  Estructuras que se usan en enunciados: condicionales e iterativos. mientras que las implícitas son las que el lenguaje define. 100 .  Estructuras que se usan en subprogramas: llamadas a subprogramas.Control de secuencia  Las estructuras para el control de la secuencia son de 3 tipos:  Estructuras que se usan en expresiones: precedencia y paréntesis.

Secuenciamiento en expresiones  La evaluación de expresiones depende de las prioridades y de los paréntesis. Se puede representar la evaluación en una estructura de árbol. el operador sigue a sus operandos. Requiere reglas de precedencia y paréntesis. sólo es adecuada para dos operandos. Ventajas parecidas a la prefija. 101 . Tres órdenes:  Prefijo (polaca prefija). La evaluación suele ser de izquierda a derecha. el operador antecede a los n operandos.  Infija. pero en la potenciación es al revés.    Se puede evaluar en un solo examen de la expresión Se puede usar para cualquier número de operandos Traducción a código fácil y almacenamiento en pila  Postfija.

que deben hacer uso de localizaciones absolutas de los datos y registros para guardar datos intermedios. pueden ser ejecutadas almacenándolas en la pila de forma fácil. 102 . luego se ejecutan usando intérpretes software.Representación de expresiones en tiempo de ejecución  Es necesario traducir las expresiones a una forma ejecutable:  Secuencias de código máquina.  Estructuras de árbol.  Formas prefija y postfija.

 Expresiones booleanas en cortocircuito. Frecuente y conceptualmente sencilla. 103 . sino pasar los operandos sin evaluar hasta que no quede otro remedio. Impaciente.Evaluación de expresiones en árbol  Se pueden presentar algunos problemas :  Reglas   de validación uniforme. Se pueden ahorrar operaciones. Perezosa. Una evaluación impaciente de expresiones booleanas puede conducir a un error no previsto por el programador. pero es difícil de implementar. Consiste en evaluar todos los operandos que cuelgan de un operador para luego realizar la operación.  Efectos colaterales.  Condiciones de error. pero del momento dela primera evaluación a la segunda cambia su valor por un efecto colateral. si un operando aparece varias veces en una expresión. no se puede ahorrar su cálculo. No evaluar la operación. determinadas operaciones en la secuencia de cálculo pueden fallar (división por 0).

que consiste. Además. 104 . En la implementacion de la unificación en PROLOG las pilas desempeñan un papel importante. en la sustitución de variables para concordar patrones congruentes con las reglas y hechos de la base de datos. salvo que se encuentre la función ! (corte). ante una consulta (predicado conteniendo variables).Secuenciamiento con expresiones no aritméticas  Este tipo de operaciones son muy utilizadas en lenguajes lógicos:     Concordancia de patrones Reescritura de términos (reglas de producción) Unificación. para el recorrido del árbol de búsqueda se emplea el RETROCESO. que hace que se produzca siempre fracaso al retroceder a la última solución plausible.

105 . La más usada es la transmisión de parámetros.     Formas de control de secuencia:     Enunciado de asignación. Leer datos desde un terminal u otro periférico. El valor de los datos puede variar la secuencia. Otras operaciones de asignación. Suele ser un operador binario que asigna a la variable izquierda el resultado de evaluar la derecha.Control de secuencia mediante enunciados  Asignaciones a objetos de datos. Composición o secuencia Alternancia Iteración Control explícito de secuencia: GOTO  Otras sentencias (ya estructuradas): BRAK y CONTINUE. Enunciado de entrada.

es le mecanismo básico para la repetición de un proceso:  Repetición simple: perform (FORTRAN)  Repetición mientras: while. expresan alternancia de dos o más enunciados:  If  Case  Enunciados de iteración. Serie de enunciados que se pueden tratar como un solo enunciado (bloques). Enunciados condicionales.  Repetición mientras con contador: for  Repetición indefinida: loop 106 .Control de secuencia estructurado   Enunciados compuestos.

107 . Condiciones excepcionales (errores y su tratamiento) Un solo arco de entrada Un solo arco de salida Unas sola ruta del arco de entrada a cada nodo. y de cada nodo al arco de salida El teorema de la estructura (Jacobini) establece que todos los programas se pueden reescribir usando los enunciados de la programación estructurada.El problema del control de secuencia estructurado.  La estructura puede ir complicándose por:    Programas primos. tienen:     Enunciado de iteración con salidas múltiples.

Control de secuencia en los subprogramas: Llamada/Regreso simple  Tienen el mismo efecto que si se copia el código del subprograma en la llamada call (regla de copia):  Los subprogramas no pueden ser recursivos  Se requieren enunciados call explícitos  Los subprogramas se deben ejecutar por completo en cada llamada  Transferencia inmediata del control en el punto de llamada  Secuencia única de ejecución 108 .

que almacena:    Datos locales Parámetros Otros elementos de datos:    Apuntador a la instrucción presente (CIP) Apuntador del ambiente presente (CEP). El ambiente de referencia es el registro de activación. Dirección de retorno 109 . cambiante. estática e invariable.Control de secuencia en los subprogramas: Subprograma simple Llamada/Regreso  Es posible el control sobre los datos:  Transmisión de parámetros  Variables locales  Variables globales  Para la implementación es necesario:  La definición del subprograma.  Un registro de activación.

110 .Control de secuencia en los subprogramas: Subprogramas recursivos   La recursividad es un procedimiento para el control de secuencia consistente en que un programa se llama a sí mismo. sólo es necesario disponer de espacio para los registros de activación de las llamadas recursivas (pila). de manera que se crea una segunda activación del subprograma durante el tiempo de vida de la primera activación. Implementación:  No es conceptualmente distinto del caso anterior.

Atributos del control de datos   Es necesario. Clases:            De variables De parámetros formales De subprogramas Para tipos definidos Para constantes definidas De enunciados De excepciones Para operaciones primitas Para constantes de literales Un nombre compuesto corresponde a una estructura de datos. Nombres. 111 . sirven para asociar un identificador a un dato. Según el ambiente de referencia. conocer el significado o valor de cada identificador que aparece en el programa. durante la ejecución. cada ASOCIACIÓN representa la pareja de un identificador y su objeto de datos.

Ambientes de referencia  Ambiente local de referencia:       Parámetros formales Variables locales Subprogramas definidos Ambiente no local de referencia. Ambiente global de referencia. Algunos identificadores son predefinidos por el lenguaje 112 . es la parte del ambiente no local. Una variable local oculta a la global del mismo nombre. son identificadores que se pueden usar desde el subprograma. Ambiente predefinido de referencia. pero no se crean en él.

 Una regla de alcance dinámico define las asociaciones en el curso dinámico de activaciones de subprogramas.  113 .Alcance estático y dinámico El alcance estático de un identificador para una asociación es el conjunto de activaciones de subprograma en las cuales la asociación es visible.

Enfoques:  Ambientes comunes explícitos  Ambientes no explícitos con base a alcance dinámico  Alcances estático  herencia 114 .Datos compartidos en subprogramas  Los objetos de daots suelen ser compartidos para la comunicación con y entre los distintos subprogramas.

El establecimiento de correspondencia entre el parámetro real y el formal puede ser:  Correspondencia de posición (lo más frecuente)  Correspondencia por nombre explícito. Parámetro real.Parámetros y transmisión de parámetros     Los parámetros y resultados transmitidos de manera explícita son el método principal para compartir datos entre subprogramas. X => 27) 115 . es una clase de objeto de datos dentro de un subprograma que aparece declarado en el encabezamiento. El parámetro real es el objeto de datos que se comparte con el subprograma llamado. ambos parámetros se aparean en la llamada:  Sub(Y => B.

116 . se pasa el puntero al parámetro real. Llamada por referencia. el parámetro real se pasa al formal como valor constante. No importa su valor inicial. Llamada por resultado. se usa sólo para transferir un resultado de regreso al programa.Métodos para transmitir parámetros      Llamada por nombre. no se puede modificar. Llamada por valor constante. Llamada por valor – resultado. se copia. se copia y caundo finaliza se escribe el valor resultado sobre el parámetro real.

y que los tipos de datos compuestos (arrays y registros) se pasen por referencia. 117 .Semántica de la transmisión  Independientemente de la la implementación los parámetros pueden ser:  De entrada (IN)  De salida (OUT)  De entrada/salida (IN/OUT)  Lo normal es que los parámetros con tipos elementales de datos admitan las 3 posibilidades.

z:integer):integer)  Problemas asociados con los parámetros de subprograma:    Verificación estática de tipos. function R(y. 118 . Referencias no locales (variables libres). es decir variables que no tienen enlaces dentro de la definición del subprograma. pues en la llamada se debe hacer esta comprobación.Subprogramas como parámetros  Para transmitir un subprograma como parámetro al subprograma que se llama hay que tener en cuenta que:  El parámetro real es el nombre del subprograma que se transmite  El parámetro formal especifica el tipo de subprograma Procedure Q(x:integer. Son necesarias reglas de asociación más reciente para referencias no locales.

aunque no es su principal objetivo  Es necesario definir el alcance y la protección para los ambientes comunes explícitos 119 .Ambientes comunes explícitos  Un ambiente común para compartir objetos de datos es la forma más sencilla de compartir datos entre subprogramas. de fortran  Paquetes en ADA.  Clases en C++ y SmallTalk.  Bloque COMMON.

Unidad Didáctica 3: “Mecanismos de los LP”   Tema 8: “Mecanismos de abstracción” 120 .

121 .