Descargar

Diseño de los lenguajes de programación

Enviado por Pablo Turmero


    edu.red

    Precedentes (I) El diseño de lenguajes es un problema complejo En los lenguajes de programación hay muchos errores de diseño Se han considerado ideas erróneas FORTRAN uso del GOTO declaración implícita de variables COBOL Sentencias demasiado largas Farragoso de escribir y leer Uso del GOTO APL si puede significar algo, lo significa LISP una sintaxis simple es más fácil de aprender Los paréntesis dificultan escribir programas La lectura es compleja por una sintaxis demasiado homogénea

    edu.red

    Precedentes (II) C el programador sabe lo que hace Obtener direcciones de variables locales Printf no comprueba el tipo y número de los argumentos C++ se puede extender C al paradigma orientado a objeto (demasiados compromisos de compatibilidad) Uso intensivo de apuntadores a objetos Lenguaje demasiado complicado Un lenguaje se puede utilizar para todo tipo de desarrollo de software Aun con muchos errores de diseño es importante estudiar los lenguajes de programación existentes ya que aportan muchas ideas

    edu.red

    Consideraciones Preliminares ¿Cual es el propósito del lenguaje? No hay un lenguaje bueno para todo Aplicación específica Bases de datos, sistemas expertos, cálculo numérico, programación simbólica, diseño algorítmico, etc. ¿Es necesario diseñar un nuevo lenguaje? Ya existe un lenguaje apropiado El nuevo lenguaje se diferencia de los existentes Se consume demasiado tiempo en el diseño e implementación de un nuevo lenguaje Es demasiado fácil diseñar un lenguaje incompleto Lenguaje demasiado especializado Sacrificar características del lenguaje por un compilador simple. Otras opciones Un modulo o librería de funciones Ampliar un lenguaje de programación

    edu.red

    Fuentes de Ideas Lenguaje natural (COBOL) Fácil de leer y escribir Ambiguo Solo se puede implementar un subconjunto Lenguajes matemáticos (APL) No ambiguos Crípticos La programación no es matemáticas Lenguajes de programación Errores de diseño (pasado) Hay que valorar cada característica de un lenguaje existente antes de incluirla en el nuevo lenguaje Pruebas y experimentos Programar con el lenguaje antes de haber acabado su diseño Sirve para detectar los problemas del diseño y tomar decisiones difíciles.

    edu.red

    Objetivos y Filosofías de Diseño Comunicación humana Prevención y detección de errores Usabilidad Efectividad Compilabilidad Eficiencia Independencia de la máquina Simplicidad Uniformidad Ortogonalidad Generalización y especialización Otras filosofías de diseño

    edu.red

    Comunicación humana (I) Se busca una comunicación eficiente entre el programador y el ordenador Un buen nivel de comunicación se da cuando los programas son leíbles No ha de ser necesaria una documentación externa al programa (minimizar) Es más importante que un programa sea leíble que escribible Un programa se escribe una vez, pero se lee muchas durante su depuración, documentación y mantenimiento. Tendencia actual a separar la interfaz de la implementación de un módulo La sintaxis ha de reflejar la semántica Reducir las manipulaciones implícitas Coerciones (coerciones de PL/I o C) ON de BASIC para eventos o excepciones Constructores y destructores de C++ (necesarios, pero complican el seguimiento del flujo de ejecución)

    edu.red

    Comunicación humana (II) El lenguaje ha de representar los patrones de pensamiento humanos No hay que crear una sintaxis pensada exclusivamente para un modelo de cómputo teórico (l-calculus) un conjunto de instrucciones de la máquina facilitar la compilación (forth) El programador no es un ordenador Que el compilador entienda una estructura es posible que el programador no Evitar incluso la posibilidad de escribirlas Reducir el conocimiento contextual El programador no funciona con una pila como el programa compilado.

    edu.red

    Prevención y detección de errores El programador comete errores Hay que prevenir los errores El programador es su fuente El programador no sabe lo que hace y el compilador ha de limitar sus acciones (EUCLID, PASCAL) Hacer imposible cierto tipo de errores Ejecutar datos -> control de flujo limitado Errores en el uso de datos -> Tipado fuerte Apuntadores erróneos -> Gestión de memoria implícita (LISP, PROLOG, ML, etc). Hay que facilitar su detección, identificación y corrección Redundancia Tener que declarar antes de utilizar. Evitar coerciones inductoras de errores float a int por su perdida de precisión Comprobaciones en tiempo de ejecución Indice de array fuera de limites Control sobre los apuntadores a NULL

    edu.red

    Lenguaje Utilizable y Efectivo Un lenguaje ha de ser fácil de utilizar Un lenguaje ha de ser fácil de aprender y recordar Evitar la necesidad de consultar el manual (C++ no cumple) Lenguaje simple (C++ no cumple) Aprendizaje incremental (PROLOG no cumple, LISP si cumple) El comportamiento del lenguaje ha de ser predecible el uso de void* de C++ es incomprensible Efectividad Los detalles de implementación no han de oscurecer las intenciones del programador Soportar abstracción Modularidad: Separar especificación de implementación Los Efectos de un cambio han de quedar localizados Evitar los trucos (programas ilegible)

    edu.red

    Otras filosofías de diseño Compilabilidad Se ha de poder compilar programa en un tiempo reducido Se ha de poder depurar o aplicar otras herramientas de análisis Eficiencia: La ejecución ha de ser rápida Independencia de la máquina Simplicidad Uniformidad: lenguaje predecible Ortogonalidad Todas las características del lenguaje se han de poder combinar Generalización y especialización La generalización dice que algo similar también es correcto, pero es difícil de implementar Hay que especializar para facilitar la implementación sin perder la utilidad del lenguaje

    edu.red

    Diseño Detallado Microestructura Estructura de las expresiones Estructuras de datos Estructuras de control Estructura de compilación Estructura de la entrada/salida

    edu.red

    Ejemplos: Lenguajes de Programación y su Diseño El lenguaje C Aplicación: programación de sistemas Programador: experto Sacar el mayor rendimiento posible del ordenador PASCAL Aplicación: docencia Programador: inexperto LISP Aplicación: procesamiento simbólico Desarrollo rápido PROLOG Aplicación: procesamiento simbólico Programación lógica Desarrollo rápido

    edu.red

    El Lenguaje C (I) Lenguaje pensado para el desarrollo de sistemas operativos (unix) Rendimiento/velocidad de ejecución Programador experto Código compacto Redimiento/Velocidad de ejecución Operaciones básicas simples Apuntadores uso para los strings y arrays Estructuras de datos referenciadas por apuntadores (paso por referencia explícito) Gestión de memoria explícita En las primeras versiones las funciones solo retornan datos que puedan ir en un registro del procesador Optimización explícita Incremento y decremento Operaciones con asignación incluida variables register

    edu.red

    El Lenguaje C (II) En contra de la velocidad Cálculos en coma flotante con la máxima precisión posible Programador experto Amplio uso de coerciones Implícitas char -> int -> double double void* Explícitas El programador puede convertir cualquier tipo de datos en cualquier otro. int -> void* Flujo de ejecución break y continue goto local long jump Obtención de direcciones Se puede obtener la dirección de cualquier variable aunque esta sea local

    edu.red

    El Lenguaje C (III) Prioridades de operadores complejas Casi cualquier combinación de operadores es aceptada por el compilador Otras cuestiones Falta de un método por defecto para la gestión de excepciones Códigos de error retornados por las funciones de la librería que continuamente ha de verificar el programa Faltan comentarios de una línea Palabras clave con diferentes significados según el contexto static Semántica ambigua Incrementos en una expresión Métodos para la escritura de programas transportables soportados por el programador Compilación condicional sizeof

    edu.red

    El Lenguaje C (IV) Sintaxis de los comentarios confundible (A=b/*p) Código compacto La mayor parte de las instrucciones se traducen a unas pocas instrucciones de código máquina Faltan instrucciones de alto nivel Strings Tratamiento por apuntadores Gestión explicita de la memoria Considerar continuamente si la reserva de memoria es suficiente No hay copia de datos compuestos Asignación array a array

    edu.red

    PASCAL Docencia Estructura muy rígida de los programas Un buen nivel de abstracción Transportable Lenguaje simplificado Falta de módulos y librerías Librería básica muy limitada Escritura farragosa de los programas Minimización del uso de coerciones Todo lo que hace el programa se indica explícitamente Pensado para la resolución de problemas por subdivisión Definiciones anidables de funciones y procedimientos Tipado fuerte

    edu.red

    LISP Sintaxis demasiado simple Difícil escritura y lectura de los programas Comprobaciones semánticas en tiempo de ejecución Variables declaradas Tipos de datos Enfoque pragmático Programación imperativa y funcional Orientado a optimizar el desarrollo frente a la velocidad de ejecución Gestión de memoria implícita Uso de listas para todo Amplia librería de funciones Diseño por etapas Funciones repetidas setq y setf Parches para mantener compatibilidad forma de creación de los places

    edu.red

    PROLOG Programación declarativa y lógica Implementación del cálculo de predicados Faltan funciones (l-prolog) Difícil modularidad Un método de programación demasiado alejado de la programación habitual Gramática de operadores extensible Totalmente transportable Modulariza las búsquedas Convierte los bucles de una búsqueda en una secuencia lineal de aplicación de predicados

    edu.red

    C++ Orientación a objeto de C Mantener la compatibilidad con C Uso masivo de apuntadores Tratamiento de excepciones no soportado por las librerías estándar Rendimiento Complica el lenguaje Static en métodos Métodos virtuales y no virtuales Templates Destructores por gestión de memoria explícita Apuntadores y referencias Otros comentarios de una línea fáciles de escribir y leer (repetición de //) Implementación parcial de las coerciones

    edu.red

    ADA Lenguaje pensado para grandes proyectos de software Facilitar el uso de librerías Interfaz separa de la implementación del módulo Control exhaustivo sobre la interfaz Fácil lectura y detección de posibles bugs Sintaxis de las instrucciones de control de flujo con marcadores claros de inicio y fin (If then else end if) Etiquetas visibles Coerciones explicitas Reducción de los errores Definición de excepciones para controlar errores de ejecución Acceso a array fuera de rango Un case del que no se selecciona ninguna opción Atributos asociados a las variables: un array tiene asociado el atributo de su tamaño

    edu.red

    Opciones en el Diseño (I) Sintaxis de control de flujo Instrucción compuesta C, PASCAL (for (;;) ; {…} Instrucciones de control de flujo con claros marcadores de inicio y fin ADA Instrucción vacía Explicita ADA (null) Implícita C, PASCAL (; o nada) Lenguaje orientado a Instrucción: ADA, PASCAL Expresión: C, funcionales Marcadores de las estructuras sintácticas Si: PASCAL, ADA No: C, C++ Expresiones Riqueza de operadores C, C++ Pobreza de operadores PASCAL, ADA

    edu.red

    Opciones en el Diseño (II) Sistema de tipos No tipado: LISP, BASIC Tipado: C, PASCAL, ADA, etc. Código genérico Datos marcados con su tipo en ejecución Tipos paramétricos templates Gestión de memoria Explicita: C, PASCAL, ADA Velocidad Implícita: LISP, PROLOG, Java, funcionales Simplicidad Gestión de errores de ejecución Responsabilidad del programador: C, C++ Responsabilidad del lenguaje ADA Excepciones sin declarar C++ Excepciones declaradas Java

    edu.red

    Opciones en el Diseño (III) Estructura declaraciones Rígida: PASCAL, ADA Poco rígida: C Libre: C++ Ámbitos Expresión LISP Instrucción compuesta C, C++, Java Función C, C++, PASCAL, ADA Espacios de nombres Clases Paquetes Módulos Coerciones Explicitas: ADA Pocas implícitas: PASCAL Muchas implícitas: C, C++