HISTORIA DE LOS LENGUAJES DE PROGRAMACION

102
FACULTAD DE INGENIERÍA FACULTAD DE INGENIERÍA E.A.P. INGENIERÍA DE SISTEMAS E E.A.P. INGENIERÍA DE SISTEMAS E INFORMÁTICA INFORMÁTICA MANUAL DEL CURSO: MANUAL DEL CURSO: Teoría de Lenguajes Teoría de Lenguajes (Unidad I) (Unidad I) Tema: Introducción a la teoría de Introducción a la teoría de Lenguajes Lenguajes Dictado por: DIANA CECILIA MUÑOZ CASANOVA DIANA CECILIA MUÑOZ CASANOVA M.S. en Ingeniería de Sistemas e Informática

description

historia de los lenguajes de programacion

Transcript of HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Page 1: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

FACULTAD DE INGENIERÍAFACULTAD DE INGENIERÍA

E.A.P. INGENIERÍA DE SISTEMAS E INFORMÁTICAE.A.P. INGENIERÍA DE SISTEMAS E INFORMÁTICA

MANUAL DEL CURSO:MANUAL DEL CURSO:

Teoría de LenguajesTeoría de Lenguajes(Unidad I)(Unidad I)

Tema:

Introducción a la teoría de LenguajesIntroducción a la teoría de Lenguajes

Dictado por:

DIANA CECILIA MUÑOZ CASANOVADIANA CECILIA MUÑOZ CASANOVA

M.S. en Ingeniería de Sistemas e Informática

CHIMBOTE – PERÚCHIMBOTE – PERÚ

20072007

Page 2: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

CAPÍTULO I: HISTORIA DE LOS LENGUAJES DE PROGRAMACIÓN

1.1. Introducción 21.2. Historia de los lenguajes de programación 31.3. Tendencias en los lenguajes de programación 7

CAPÍTULO II: EVOLUCIÓN DE LOS LENGUAJES DE PROGRAMACIÓN

2.1. Evolución de los lenguajes de programación 112.1.1. Estructurados vs. No estructurados 112.1.2. 1985-1990 y el nacimiento del xbase 112.1.3. Los primeros años, 1990-1995: las bases de datos relacionales 122.1.4. La segunda mitad, 1995-2000: la orientación a objetos 122.1.5. El fin de los lenguajes D.O.S. 132.1.6. 2000 y más allá: lenguajes visuales 132.1.7. Una visión a la web y al futuro: html, perl, php, pithon, java y otros 14

2.2. Generaciones de lenguajes de programación 152.3. Tipos de lenguaje de programación según su campo de aplicación. 152.4. Tipos de lenguaje de programación en función al estilo de programar 162.5. Lenguajes imperativos 162.6. Lenguajes funcionales 18

2.6.1. Concepto matemático de función. 182.6.2. Concepto de lenguajes funcionales. 192.6.3. Categorías de lenguajes funcionales. 202.6.4. Problemas del modelo imperativo 20

2.7. Lenguajes lógicos (declarativos) 222.8. Lenguajes orientados a objetos 262.9. Lenguajes con concurrencia 272.10. Evolución de los lenguajes de programación declarativos 292.11. Evolución de los lenguajes de programación orientado a objetos e

Imperativos 30

CAPÍTULO III: CONCEPTOS EN LOS LENGUAJES DE PROGRAMACIÓN

3.1. ¿Qué es lo que constituye un buen lenguaje? 313.1.1. Atributos de un buen lenguaje 313.1.2. Estandarización de los lenguajes 32

3.2. Sintaxis de lenguajes de programación 323.3. Tipos de datos 333.4. Abstracción 343.5. Abstracción en programación 343.6. Clases de abstracción 35

3.6.1. Abstracción de control 35

Page 3: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

3.6.2. Abstracción de datos. 373.7. Tipos abstractos de datos (TADS) 373.8. Lenguajes de programación y TADS 373.9. Lenguajes de programación que deberías aprender 39

3.9.1. PHP 393.9.2. C# 393.9.3. AJAX 403.9.4. Javascript 403.9.5. PERL 413.9.6. C 413.9.7. Ruby y ruby on rails 413.9.8. ASP 42

CAPÍTULO IV: LENGUAJES DE BAJO, MEDIO Y ALTO NIVEL

4.1. Introducción 434.2. Lenguajes de bajo nivel 43

4.2.1. Lenguaje máquina. 444.2.2. Ensamblador. 44

A) Ventajas del lenguaje ensamblador 45B) Desventajas del lenguaje ensamblador 48

4.3. Lenguajes de medio nivel 494.4. Lenguajes De Alto Nivel 524.5. Generadores de aplicaciones o 4º nivel 53

CAPÍTULO V: ELEMENTOS DE UN LENGUAJE DE PROGRAMACIÓN

5.1. Elementos sintácticos de un lenguaje 545.2. Tipos de datos 555.3. Notaciones de expresiones 565.4. Propiedad asociativa y precedencia 565.5. Representación de árbol para expresiones 575.6. Evaluación de expresiones 57

5.6.1. Evaluación mediante la reconstrucción de un árbol 575.6.2. Evaluación mediante una pila 58

A) Algoritmo para transformar una notación infija a postfija 58B) Tabla de prioridades. 60C) Algoritmo (pseudocódigo) 60

Page 4: HISTORIA DE LOS LENGUAJES DE PROGRAMACION
Page 5: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

CAPÍTULO I: HISTORIA DE LOS LENGUAJES DE

PROGRAMACIÓN

1.1. INTRODUCCIÓN

Una computadora es una máquina que solo comprende las instrucciones que se le

den en un determinado formato. Cada máquina reconoce y ejecuta un número de

instrucciones diferentes que se agrupan en los distintos lenguajes de

programación.

Un lenguaje de programación es un conjunto limitado de palabras y de símbolos

que representan procedimientos, cálculos, decisiones y otras operaciones que

pueden ejecutar una computadora. A pesar de que en este trabajo parte de la

división de lenguajes de programación en imperativos y declarativos (los cuales a

su vez se dividen en numerosos subgrupos), la clasificación más común y básica

que suele hacerse de los lenguajes de programación es la que los divide en

lenguajes de bajo y de alto nivel. Los lenguajes de programación de bajo nivel

fueron los primeros que surgieron y se llaman así porque están directamente

relacionados con el hardware del computador, es decir, el usuario introduce una

serie de códigos numéricos que la máquina va a interpretar como instrucciones.

Para usar este lenguaje, el programador tenía que conocer el funcionamiento de la

máquina al más bajo nivel y los errores de programación eran muy frecuentes.

Los lenguajes de alto nivel surgieron con posterioridad con el primer compilador

de FORTRAN (FORmula TRANslation), que, como su nombre indica, inició

como un "simple" esfuerzo de traducir un lenguaje de fórmulas, al lenguaje

ensamblador y por consiguiente al lenguaje de máquina, facilitando la labor a los

programadores. A partir de FORTRAN, se han desarrollado innumerables

lenguajes, que siguen el mismo concepto: facilitar la vida al programador,

aumentando la productividad. Estos lenguajes usan un número reducido de

instrucciones (normalmente en inglés) que siguen unas estrictas reglas

gramaticales que se conocen como sintaxis del lenguaje. Pero aunque el

programador de esta forma se distancie del hardware del computador, este sigue

trabajando en lenguaje máquina. Por ello se hace necesaria una traducción a una

Page 6: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

secuencia de instrucciones interpretables por el computador. Esta labor es llevada

a cabo por los compiladores y los intérpretes.

El compilador es un programa que se encarga de la traducción global del programa

realizado por el usuario. Esta operación recibe el nombre de compilación. El

programa es traducido completamente antes de que se ejecute, por lo que la

ejecución se realiza en un periodo muy breve. El intérprete por el contrario lleva a

cabo una traducción inmediata en el momento de la ejecución, es decir, irá

ejecutando las instrucciones una a una haciendo que el proceso requiera un

periodo de tiempo sensiblemente mayor del que necesitaría un compilador. Los

intérpretes son usados para traducir programas de alta dificultad de

implementación, en estos casos, las órdenes a traducir son de tal complejidad que

no merece la pena crear un compilador ya que este también tendría que ser de una

complejidad por encima de lo normal.

Hay que mencionar la existencia de lenguajes que combinan características de los

de alto nivel y los de bajo nivel (es decir, Ensamblador). Un ejemplo es C:

contiene estructuras de programación de alto nivel; sin embargo, fue diseñado con

muy pocas instrucciones, las cuales son sumamente sencillas, fáciles de traducir al

lenguaje de la máquina; y requiere de un entendimiento apropiado de cómo

funciona la máquina, el uso de la memoria, etcétera. Por ello, algunos consideran a

lenguajes como C (que fue diseñado para hacer sistemas operativos), lenguajes de

nivel medio, si bien, son considerados mayoritariamente de bajo nivel.

1.2. HISTORIA DE LOS LENGUAJES DE PROGRAMACIÓN

Los primeros lenguajes de programación surgieron de la idea de Charles Babagge,

la cual se le ocurrió a este hombre a mediados del siglo XIX. Era un profesor

matemático de la universidad de Cambridge e inventor ingles, que la principio del

siglo XIX predijo muchas de las teorías en que se basan los actuales ordenadores.

Consistía en lo que él denominaba la maquina analítica, pero que por motivos

técnicos no pudo construirse hasta mediados del siglo XX. Con él colaboro Ada

Lovedby, la cual es considerada como la primera programadora de la historia,

pues realizo programas para aquélla supuesta maquina de Babagge, en tarjetas

perforadas. Como la maquina no llego nunca a construirse, los programas de Ada,

lógicamente, tampoco llegaron a ejecutarse, pero si suponen un punto de partida

Page 7: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

de la programación, sobre todo si observamos que en cuanto se empezó a

programar, los programadores utilizaron las técnicas diseñadas por Charles

Babagge, y Ada, que consistían entre otras, en la programación mediante tarjetas

perforadas. A pesar de ello, Ada ha permanecido como la primera programadora

de la historia. Se dice por tanto que estos dos genios de antaño, se adelantaron un

siglo a su época, lo cual describe la inteligencia de la que se hallaban dotados.

En 1823 el gobierno Británico lo apoyo para crear el proyecto de una máquina de

diferencias, un dispositivo mecánico para efectuar sumas repetidas. Pero Babagge

se dedico al proyecto de la máquina analítica, abandonando la maquina de

diferencias, que se pudiera programar con tarjetas perforadas, gracias a la creación

de Charles Jacquard (francés). Este hombre era un fabricante de tejidos y había

creado un telar que podía reproducir automáticamente patrones de tejidos, leyendo

la información codificada en patrones de agujeros perforados en tarjetas de papel

rígido. Entonces Babagge intento crear la máquina que se pudiera programar con

tarjetas perforadas para efectuar cualquier cálculo con una precisión de 20 dígitos.

Pero la tecnología de la época no bastaba para hacer realidad sus ideas. Si bien las

ideas de Babagge no llegaron a materializarse de forma definitiva, su contribución

es decisiva, ya que los ordenadores actuales responden a un esquema análogo al de

la máquina analítica. En su diseño, la máquina constaba de cinco unidades básicas:

1) Unidad de entrada, para introducir datos e instrucciones.

2) Memoria, donde se almacenaban datos y resultados intermedios.

3) Unidad de control, para regular la secuencia de ejecución de las operaciones.

4) Unidad Aritmético-Lógica, que efectúa las operaciones.

5) Unidad de salida, encargada de comunicar al exterior los resultados.

Charles Babbage, conocido como el "padre de la informática" no pudo completar

en aquella época la construcción del computador que había soñado, dado que

faltaba algo fundamental: la electrónica. El camino señalado de Babbage, no fue

nunca abandonado y siguiéndolo, se construyeron las primeras computadoras.

Al desarrollarse las primeras computadoras electrónicas, se vio la necesidad de

programarlas, es decir, de almacenar en memoria la información sobre la tarea que

iban a ejecutar. Las primeras se usaban como calculadoras simples; se les

indicaban los pasos de cálculo, uno por uno.

Page 8: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

John Von Neumann desarrolló el modelo que lleva su nombre, para describir este

concepto de "programa almacenado". En este modelo, se tiene una abstracción de

la memoria como un conjunto de celdas, que almacenan simplemente números.

Estos números pueden representar dos cosas: los datos, sobre los que va a trabajar

el programa; o bien, el programa en sí.

¿Cómo es que describimos un programa como números? Se tenía el problema de

representar las acciones que iba a realizar la computadora, y que la memoria, al

estar compuesta por switches correspondientes al concepto de bit, solamente nos

permitía almacenar números binarios.

La solución que se tomó fue la siguiente: a cada acción que sea capaz de realizar

nuestra computadora, asociarle un número, que será su código de operación

(opcode). Por ejemplo, una calculadora programable simple podría asignar los

opcodes:

1 = SUMA, 2 = RESTA, 3 = MULTIPLICA, 4 = DIVIDE.

Supongamos que queremos realizar la operación 5 * 3 + 2, en la calculadora

descrita arriba. En memoria, podríamos "escribir" el programa de la siguiente

forma: Localidad Opcode Significado Comentario 0 5 5 En esta localidad,

tenemos el primer número de la fórmula 1 3 * En esta localidad, tenemos el

opcode que representa la multiplicación. 2 3 3 En esta localidad, tenemos el

segundo número de la fórmula 3 1 + En esta localidad, tenemos el opcode que

representa la suma. 4 2 2 En esta localidad, tenemos el último número de la

fórmula. Podemos ver que con esta representación, es simple expresar las

operaciones de las que es capaz el hardware (en este caso, nuestra calculadora

imaginaria), en la memoria.

La descripción y uso de los opcodes es lo que llamamos lenguaje de máquina. Es

decir, la lista de códigos que la máquina va a interpretar como instrucciones,

describe las capacidades de programación que tenemos de ella; es el lenguaje más

primitivo, depende directamente del hardware, y requiere del programador que

conozca el funcionamiento de la máquina al más bajo nivel.

Los lenguajes más primitivos fueron los lenguajes de máquina. Esto, ya que el

hardware se desarrolló antes del software, y además cualquier software finalmente

tiene que expresarse en el lenguaje que maneja el hardware.

La programación en esos momentos era sumamente tediosa, pues el programador

tenía que "bajarse" al nivel de la máquina y decirle, paso a pasito, cada punto de la

Page 9: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

tarea que tenía que realizar. Además, debía expresarlo en forma numérica; y por

supuesto, este proceso era propenso a errores, con lo que la productividad del

programador era muy limitada. Sin embargo, hay que recordar que en estos

momentos, simplemente aún no existía alternativa.

El primer gran avance que se dio, fue la abstracción dada por el Lenguaje

Ensamblador, y con él, el nacimiento de las primeras herramientas automáticas

para generar el código máquina. Esto redujo los errores triviales, como podía ser el

número que correspondía a una operación, que son sumamente engorrosos y

difíciles de detectar, pero fáciles de cometer. Sin embargo, aún aquí es fácil para el

programador perderse y cometer errores de lógica, pues debe bajar al nivel de la

forma en que trabaja el CPU, y entender bien todo lo que sucede dentro de él.

Con el desarrollo en los 50s y 60s de algoritmos de más elevado nivel, y el

aumento de poder del hardware, empezaron a entrar al uso de computadoras

científicos de otras ramas; ellos conocían mucho de Física, Química y otras ramas

similares, pero no de Computación, y por supuesto, les era sumamente complicado

trabajar con lenguaje Ensamblador en vez de fórmulas. Así, nació el concepto de

Lenguaje de Alto Nivel, con el primer compilador de FORTRAN (FORmula

TRANslation), que, como su nombre indica, inició como un "simple" esfuerzo de

traducir un lenguaje de fórmulas, al lenguaje ensamblador y por consiguiente al

lenguaje de máquina. A partir de FORTRAN, se han desarrollado innumerables

lenguajes, que siguen el mismo concepto: buscar la mayor abstracción posible, y

facilitar la vida al programador, aumentando la productividad, encargándose los

compiladores o intérpretes de traducir el lenguaje de alto nivel, al lenguaje de

computadora.

Hay que notar la existencia de lenguajes que combinan características de los de

alto nivel y los de bajo nivel (es decir, Ensamblador). El ejemplo mas apropiado

podría ser el lenguaje C ya que puede acceder a los registros del sistema, trabajar

con direcciones de memoria, todas ellas características de lenguajes de bajo nivel

y a la vez realizar operaciones de alto nivel.

Page 10: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

1.3. TENDENCIAS EN LOS LENGUAJES DE PROGRAMACIÓN

El estudio de los lenguajes de programación agrupa tres intereses diferentes; el del

programador profesional, el del diseñador del lenguaje y del Implementador del

lenguaje.

Además, estos tres trabajos han de realizarse dentro de las ligaduras y capacidades

de la organización de una computadora y de las limitaciones fundamentales de la

propia "calculabilidad".

El termino "el programador" es un tanto amorfo, en el sentido de

que camufla importantes diferencias entre distintos niveles y aplicaciones de la

programación. Claramente el programador que ha realizado un curso de doce

semanas en COBOL y luego entra en el campo del procesamiento de datos es

diferente del programador que escribe un compilador en Pascal, o del

programador que diseña un experimento de inteligencia artificial en LISP, o

del programador que combina sus rutinas de FORTRAN para resolver un

problema de ingeniería complejo, o del programador que desarrolla un sistema

operativo multiprocesador en ADA.

El "diseñador del lenguaje" es también un termino algo nebuloso.

Algunos lenguajes (como APL y LISP) fueron diseñados por una sola persona

con un concepto único, mientras que otros (FORTRAN y COBOL) son el

producto de desarrollo de varios años realizados por comités de diseño de

lenguajes.

El "Implementador del lenguaje" es la persona o grupo que

desarrolla un compilador o interprete para un lenguaje sobre una maquina

particular o tipos de maquinas. Mas frecuentemente, el primer compilador para

el lenguaje Y sobre la maquina X es desarrollada por la corporación que

manufactura la maquina X. Por ejemplo, hay varios compiladores de Fortran

en uso; uno desarrollado por IBM para una maquina IBM, otro desarrollado

por DEC para una maquina DEC, otro por CDC, y así sucesivamente. Las

compañías de software también desarrollan compiladores y también lo hacen

los grupos de investigación de las universidades

Page 11: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Hay también muchos aspectos compartidos entre los programadores, diseñadores

de un lenguaje implementadores del mismo. Cada uno debe comprender las

necesidades y ligaduras que gobiernan las actividades de los otros dos.

Hay, al menos, dos formas fundamentales desde las que pueden verse o

clasificarse los lenguajes de programación: por su nivel y por principales

aplicaciones. Además, estas visiones están condicionadas por la visión histórica

por la que ha transcurrido el lenguaje

Los "Lenguajes Declarativos" son los más parecidos al castellano o ingles en su potencia

expresiva y funcionalidad están en el nivel mas alto respecto a los otros. Son

fundamentalmente lenguajes de ordenes, dominados por sentencias que expresan "Lo que

hay que hacer" en ves de "Como hacerlo".

Los lenguajes de " Alto Nivel" son los mas utilizados como lenguaje de programación.

Aunque no son fundamentalmente declarativos, estos lenguajes permiten que los

algoritmos se expresen en un nivel y estilo de escritura fácilmente legible y comprensible

por otros programadores.

Los "Lenguajes Ensambladores" y los "Lenguajes Maquina" son dependientes de la

maquina. Cada tipo de maquina, tal como VAX de digital, tiene su propio lenguaje

maquina distinto y su lenguaje ensamblador asociado. El lenguaje Ensamblador es

simplemente una representación simbólica del lenguaje maquina asociado, lo cual permite

una programación menos tediosa que con el anterior.

La programación de un lenguaje de alto nivel o en un lenguaje ensamblador requiere, por

tanto, algún tipo de interfaz con el lenguaje maquina para que el programa pueda

ejecutarse. Las tres interfaces mas comunes: un "ensamblador" , un "compilador" y un

"interprete". El ensamblador y el compilador traduce el programa a otro equivalente en el

lenguaje X de la maquina "residente" como un paso separado antes de la ejecución. Por

otra parte, el interprete ejecuta directamente las instrucciones en un lenguaje Y de alto

nivel, sin un paso de procesamiento previo.

Algunos lenguajes son lenguajes principalmente interpretados, como APL, PROLOG y

LISP. El resto de los lenguajes -- Pascal, FORTRAN, COBOL, PL/I, SNOBOL, C, Ada y

Modula-2 – son normalmente lenguajes compilados. En algunos casos, un compilador

estará utilizable alternativamente para un lenguaje interpretado (tal como LISP) e

inversamente (tal como el interprete SNOBOL4 de los laboratorios Bell). Frecuentemente

la interpretación es preferible a la compilación en un entorno de programación

experimental o de educación, donde cada nueva ejecución de un programa implicado un

cambio en el propio texto del programa. La calidad de diagnosis y depuración que

soportan los lenguajes interpretados es generalmente mejor que la de los lenguajes

Page 12: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

compilados, puesto que los mensajes de error se refieren directamente a sentencias del

texto del programa original. Además, la ventaja de la eficiencia que se adjudica

tradicionalmente a los lenguajes compilados frente a los interpretados puede pronto ser

eliminado, debido a la evolución de las maquinas cuyos lenguajes son ellos

mismos1lenguajes de alto nivel. Como ejemplo de estos están las nuevas maquinas LISP,

las cuales han sido diseñadas recientemente por Symbolics y Xerox Corporations.

Los lenguajes de Programación son tomados de diferentes perspectivas. Es importante

para un programador decidir cuales conceptos emitir o cuales incluir en la programación.

Con frecuencia el programador es osado a usar combinaciones de conceptos que hacen al

lenguaje "DURO" de usar, de entender e implementar. Cada programador tiene en mente

un estilo particular de programación, la decisión de incluir u omitir ciertos tipos de datos

que pueden tener una significativa influencia en la forma en que el Lenguaje es usado, la

decisión de usar u omitir conceptos de programación o modelos.

Existen cinco estilo de programación y son los siguientes:

1. Imperativa : Entrada, procesamiento y salidas de Datos.

2. Funcional : "Funciones", los datos son funciones, los resultados pueden ser un valor

o una función.

3. Lógico : {T,F} + operaciones lógicos (Inteligencia Artificial).

4. Orientados a Objetos: Clases, encapsulamiento de datos Herencia de datos,

polimorfismo

5. Concurrente.

El programador, diseñador e implementador de un lenguaje de programación deben

comprender la evolución histórica de los lenguajes para poder apreciar por que presentan

características diferentes. Por ejemplo, los lenguajes "mas jóvenes" desaconsejan (o

prohiben) el uso de las sentencias GOTO como mecanismo de control inferior, y esto es

correcto en el contexto de las filosofías actuales de ingeniería del software y

programación estructurada. Pero hubo un tiempo en que la GOTO, combinada con la IF,

era la única estructura de control disponible; el programador no dispone de algo como la

construcción WHILE o un IF-THEN-ELSE para elegir. Por tanto, cuando se ve un

lenguaje como FORTRAN, el cual tiene sus raíces en los comienzos de la historia de los

lenguajes de programación, uno no debe sorprenderse de ver la antigua sentencia GOTO

dentro de su repertorio.

Lo mas importante es que la historia nos permite ver la evolución de familias de

lenguajes de programación, ver la influencia que ejercer las arquitecturas y aplicaciones

de las computadoras sobre el diseño de lenguajes y evitar futuros defectos de diseño

aprendido las lecciones del pasado. Los que estudian se han elegido debido a su mayor

Page 13: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

influencia y amplio uso entre los programadores, así como por sus distintas características

de diseño e implementacion. Colectivamente cubren los aspectos más importantes con los

que ha de enfrentarse el diseñado de lenguajes y la mayoría de las aplicaciones con las

que se enfrenta el programador.

También varios lenguajes están prefijados por las letras ANSI. Esto significa que el

American National Standards Institute ha adoptado esa versión del lenguaje como el

estándar nacional. Una vez que un lenguaje esta estandarizado, las maquinas que

implementan este lenguaje deben cumplir todas las especificaciones estándares,

reforzando así el máximo de transportabilidad de programas de una maquina a otra. La

policía federal de no comprar maquinas que no cumplan la versión estándar de cualquier

lenguaje que soporte tiende a "fortalecer" el proceso de estandarizacion, puesto que el

gobierno es, con mucho, el mayor comprador de computadoras de la nación.

Finalmente, la notación algebraica ordinaria, por ejemplo, influyo fuertemente en el

diseño de FORTRAN y ALGOL. Por otra parte, el ingles influyo en el desarrollo del

COBOL. El lambda calculo de Church dio los fundamentos de la notación funcional de

LISP, mientras que el algoritmo de Markov motivo el estilo de reconocimiento de formas

de SNOBOL. La arquitectura de computadoras de Von Neumann, la cual fue una

evolución de la maquina mas antigua de Turing, es el modelo básico de la mayoría de los

diseños de computadoras de las ultimas tres décadas. Esta maquina no solo influyeron en

los primeros lenguajes sino que también suministraron el esqueleto operacional sobre el

que evoluciono la mayoría de la programación de sistemas.

Una discusión mas directa de todos estos primeros modelos no están entre los objetivos de

este texto. Sin embargo, es importante apuntar aquí debido a su fundamental influencia en

la evolución de los primeros lenguajes de programación, por una parte, y por su estado en

el núcleo de la teoría de la computadora, por otra. Mas sobre este punto, cualquier

algoritmo que pueda describirse en ingles o castellano puede escribirse igualmente como

una maquina de Turing (maquina de Von Neumann), un algoritmo de Markov o una

función recursiva. Esta sección, conocida ampliamente como "tesis de Church", nos

permite escribir algoritmos en distintos estilos de programación (lenguajes) sin sacrificar

ninguna medida de generalidad, o potencia de programación, en la transición.

Page 14: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

CAPÍTULO II: EVOLUCIÓN DE LOS LENGUAJES DE

PROGRAMACIÓN

2.1. EVOLUCIÓN DE LOS LENGUAJES DE PROGRAMACIÓN

2.1.1. ESTRUCTURADOS VS. NO ESTRUCTURADOS

A partir de C el gran lenguaje, y Pascal; se dividen los lenguajes en

estructurados (aquellos que en su codificación usaban una estructura jerárquica

de procedimientos y funciones), en contraposición a los lenguajes no

estructurados como el Basic cuya codificación se basaba en líneas de

programación, permitiendo al programador "saltar" de una línea de instrucción

a otra, haciendo que el código fuera algunas veces inentendible y muy difícil

de mantener (modificar) porque no seguía una estructura.

Basic de todos modos evolucionó, primero con el ahora primitivo GW Basic,

teniendo su máxima expresión con el Quick Basic del D.O.S. 5.0, el cual ya

incluía algunos conceptos mas de avanzada y más "aggiornados" a lo que eran

sus contrapartes estructuradas.

2.1.2. 1985-1990 Y EL NACIMIENTO DEL XBASE

DBase fue el gran desarrollo para base de datos de los años 80. Bajo la batuta

de la firma Ashton Tate, empresa que dio origen a un interprete de bases de

datos muy sencillo y poderoso: dBbase II. Luego vinieron el dBase III+ que

hizo furor, y la etapa de la decadencia para dBase: el dBase IV, ya bajo la

dirección de Borland.

Así surgió el gran compilador Clipper, de Nantucket Corp., en su versión

Autumm 86 que permitía generar ejecutables libres de royalties y sin runtimes,

incluso tomando en forma directa el código dBase. Pero no solo era eso,

proveia cientos de comandos y funciones para potenciar al dBase.

Al ver el éxito de dBase y Clipper, surgió la empresa Fox Software que

desarrollo el FoxBase (un clon de dBase III+) y supero al "maestro" con su

versión Fox Plus, pero aun así, nunca pudo superar a Clipper ya que siempre

lidio con su política de necesitar de runtimes para su ejecución, cosa que

Clipper nunca necesitó.

Page 15: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

2.1.3. LOS PRIMEROS AÑOS, 1990-1995: LAS BASES DE DATOS

RELACIONALES

A principios de la década pasada, se nota la evolución de los lenguajes de

programación. En forma profesional y aplicaciones de alto nivel, el lenguaje

preferido era C.

Para el aprendizaje se usaba Pascal, que permitía inculcar el concepto de

programación estructurada.

También Basic, era un lenguaje utilizado, no en pocas ocasiones en forma

profesional, aunque con ciertas limitaciones; su reinado estuvo en los años 80.

En lenguaje C, fue y todavía es el gran artífice de la computación actual. A

partir de el se desarrollaron compiladores que realmente constituían otros

lenguajes de programación. Es decir un lenguaje que crea otros lenguajes. Tal

es el caso de la estrella de la primera mitad de la década pasada: Clipper de

Nantucket Corp., el gran compilador de lenguaje Xbase. Clipper fue criticado

por los profesionales de la programación quienes aducían que no era un

lenguaje, sino un simple compilador nacido de la necesidad de aligerar la

ejecución de código del Interprete que le dio su origen, es decir el dBase. Pero

realmente Clipper, gracias a llevar dentro su código un corazón de lenguaje C,

fue muy fácil de utilizar y alcanzo gran popularidad.

Se desarrollaron librería externas, y con la programación al estilo C a partir de

su versión 5.0 y la inclusión de objetos, se convirtió en uno de los favoritos de

la programación administrativa, junto con Pascal.

Todos los lenguajes Xbase se basaban en el concepto de bases de datos

relacionales, es decir la agrupación de la información en forma de tablas,

denominadas campos y registros, cada uno de ellos preformateados para

recibir cierto tipo de dato (ej: fechas, caracteres, números, valores lógicos,

etc.); pudiendo "unir" diferentes bases por medio de campos comunes.

2.1.4. LA SEGUNDA MITAD, 1995-2000: LA ORIENTACIÓN A OBJETOS

A medida que los años van pasando el concepto de Bases relacionales empieza

a decaer relativamente, surge entonces una variante que se aplica a todos los

lenguajes: La orientación a objetos. Ya no solo se habla de programación

estructurada, sino que los módulos de programación son vistos como objetos,

las estructuras representan objetos y/o funciones que se adaptan en forma

Page 16: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

general a procesos específicos es la maximización de la programación

modular.

El modelo de objetos engloba los conceptos de encapsulación, herencia y

poliformismo, el cual se aplica a los datos y al tipo de bases de datos que

almacena la información.

La orientación a objetos significa la agrupación de entidades de datos de forma

global, de tal manera que puedan ser interpretados de una forma común por

una misma estructura de programación.

2.1.5. EL FIN DE LOS LENGUAJES D.O.S.

Windows 95 marca el comienzo del fin de la programación D.O.S. y por lo

tanto de los lenguajes basados en este. Este proceso no fue enérgico, todavía

hoy, estamos viviendo esta etapa. Todavía hay numerosos y excelentes

sistemas desarrollados bajo entorno D.O.S. ejecutándose pero cada vez son los

menos.

Veamos que hicieron los lenguajes D.O.S. para mantenerse en el mercado:

Clipper trato de evolucionar hacia Windows bajo la batuta de Computer

Associates con el nombre de Visual Objects, el cual fue un fracaso. Al igual

que Visual Dbase 5.0 bajo la órbita de Borland.

Los únicos "sobrevivientes" al menos en esencia son Visual Fox (Microsoft),

Visual Basic (Microsoft), Delphi (Borland) y Visual C (Microsoft)

2.1.6. 2000 Y MÁS ALLÁ: LENGUAJES VISUALES

Con al llegada de Windows todo es Visual, todo es iconos, todo es botones,

todo es Ventanas. Para programar en lenguajes visuales, primero hay que

comprender lo que es Windows. La forma de programar los sistemas

evolucionó radicalmente. Con Windows es preciso programar conservando las

convenciones del mismo, guardando sus características y funcionalidades. Los

sistemas hechos para Windows, deben ser tan Windows como el propio

sistema operativo.

La forma de programar se basa en objetos, cada uno de los cuales tiene sus

Propiedades y funciones. Se basa en la programación de eventos para dichos

objetos. Otro detalle es que la programación se basa en componentes (OLE,

OCX, ActiveX), los cuales reducen notablemente el trabajo de la

Page 17: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

programación al proporcionar herramientas antes impensadas en la

programación D.O.S.

Todos los lenguajes visuales ofrecen RAD (Rapid Aplication Development) o

Wizzards; con lo cual comenzaron a prometer hacer aplicaciones en poco

tiempo, incluso para inexpertos. Lejos estaban ya los tiempos en que

programar era solo usar un simple editor de textos. Ahora las herramientas de

programación son poderosas. Son casi un sistema operativo, por asi decirlo;

con entornos de desarrollo avanzado y excelentes Debuggers. Las incursiones

cada vez mas innovadoras de Microsoft parecen imponer a la web como el

centro de desarrollo de aplicaciones: Microsoft .NET

2.1.7. UNA VISIÓN A LA WEB Y AL FUTURO: HTML, PERL, PHP,

PITHON, JAVA Y OTROS

Internet ha sido el disparador de nuevos lenguajes tales como el HTML que es

el lenguaje de programación de las páginas WEB para hipertexto. El mismo

constituye una codificación bastante simple, basada en marcadores (TAGs).

De la misma manera, cuando se hace necesario proveer de funciones

adicionales a un servicio web se recurre a Perl o a Pithon que son lenguajes

que nos permiten escribir scripts para ser alojados en los servidores a efectos

de proveer contadores, estadísticas, rankings, etc.

Por otra parte Java, bajo la dirección de SUN, constituye la idea de la

programación abierta y universal para las aplicaciones de escritorio, pero

todavía los estándares visuales (C, Basic y Delphi), son demasiado poderosos

como para desplazarlos, a pesar de que Java promete también ser un lenguaje

de excelentes prestaciones. Las nuevas tecnologías WEB inundan el mercado:

PHP, ASP, XML, DHTML, XHTML, AJAX lo cual enriquecen la forma de

manejar la información y su presentación al usuario final.

Page 18: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

2.2. GENERACIONES DE LENGUAJES DE PROGRAMACIÓN

La evolución de los lenguajes de programación se puede dividir en 5 etapas o

generaciones.

1. Primera generación: lenguaje maquina.

2. Segunda generación: se crearon los primeros lenguajes ensambladores.

3. Tercera generación: se crean los primeros lenguajes de alto nivel. Ej. C,

Pascal, Cobol…

4. Cuarta generación. Son los lenguajes capaces de generar código por si

solos, son los llamados RAD, con lo cuales se pueden realizar aplicaciones sin

ser un experto en el lenguaje. Aquí también se encuentran los lenguajes

orientados a objetos, haciendo posible la reutilización d partes del código para

otros programas.

5. Quinta generación: aquí se encuentran los lenguajes orientados a la

inteligencia artificial.. Ej. PROLOG

2.3. TIPOS DE LENGUAJE DE PROGRAMACIÓN SEGÚN SU CAMPO DE

APLICACIÓN.

Aplicaciones científicas.

En este tipo de aplicaciones predominan las operaciones numéricas o

matriciales propias de algoritmos matemáticos. Lenguajes adecuados son

FORTRAN y PASCAL

Aplicaciones en procesamiento de datos.

En estas aplicaciones son frecuentes las operaciones de creación,

mantenimiento y consulta sobre ficheros y bases de datos. Dentro de este

campo estarían aplicaciones de gestión empresarial, como programas de

nominas, contabilidad facturación, control de inventario, etc. Lenguajes aptos

para este tipo de aplicaciones son COBOL y SQL.

Aplicaciones de tratamiento de textos.

Estas aplicaciones están asociadas al manejo de textos en lenguaje natural. Un

lenguaje muy adecuado para este tipo de aplicaciones es el C.

Page 19: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Aplicaciones en inteligencia artificial.

Dentro de este campo, destacan las aplicaciones en sistemas expertos, juegos,

visión artificial, robótica. Los lenguajes más populares dentro del campo de la

inteligencia artificial son LISP y PROLOG

Aplicaciones de programación de sistemas.

En este campo se incluirían la programación de software de interfaz entre el

usuario y el hardware, como son los módulos de un sistema operativo y los

traductores. Tradicionalmente para estas aplicaciones se utilizaba el

Ensamblador, no obstante en la actualidad se muestran muy adecuados los

lenguajes ADA, MODULA-2 y C.

Lenguajes de Internet.

HTML, JAVA, Perl, PHP, etc

2.4. TIPOS DE LENGUAJE DE PROGRAMACIÓN EN FUNCIÓN AL

ESTILO DE PROGRAMAR

Lenguajes imperativos

Lenguajes funcionales

Lenguajes lógicos (declarativos)

Lenguajes orientados a objetos

Lenguajes con concurrencia

2.5. LENGUAJES IMPERATIVOS

En este tipo de lenguajes, cuyo origen está ligado a la propia arquitectura de von

Neumann, la arquitectura consta de una secuencia de celdas, llamadas memoria,

en la cual se pueden guardar en forma codificada, lo mismo datos que

instrucciones; y de un procesador, el cual es capaz de ejecutar de manera

secuencial una serie de operaciones, principalmente aritméticas y booleanas,

llamadas comandos. En general, un lenguaje imperativo ofrece al programador

conceptos que se traducen de forma natural al modelo de la máquina.Los lenguajes

Page 20: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

imperativos más destacados de la historia han sido: FORTRAN, Algol, Pascal, C,

Modula-2, Ada

El programador, al utilizar un lenguaje imperativo, por lo general tiene que

traducir la solución abstracta del problema a términos muy primitivos, cercanos a

la máquina. La distancia entre el nivel del razonamiento humano y lo expresable

por los lenguajes imperativos causa que sus programas sean más "comprensibles"

para la máquina que para el hombre. Esta desventaja para nosotros, reflejada en la

dificultad que tenemos al construir programas en un lenguaje imperativo, se

vuelve una ventaja en el momento de la generación del código. El programa está

expresado en términos tan cercanos a la máquina, que el código generado es

relativamente parecido al programa original, lo que permite cierta eficiencia en la

ejecución.

Ejemplo:

Este sería el código de un programa que determina el factorial de un número en un

lenguaje imperativo inventado:

procedimiento factorial(entero n){

entero resultado = 1;

mientras (n > 0) {

resultado = resultado * n;

n = n - 1;

}

devuelve resultado;

}

Este procedimiento (o función) recibe un número entero n. Declara una variable

resultado que será el resultado final a devolver. Inicialmente, tiene como valor el

1. Después llega una estructura de control denominada bucle, que se ejecuta

mientras la condición expresada entre los paréntesis (n > 0) sea cierta. Dentro del

bucle se multiplica la variable resultado por n y el valor se deja de nuevo en

resultado. La siguiente sentencia (n = n - 1) es necesaria para ir haciendo el

factorial, así como para salir en algún momento del bucle. Por último, tras salir del

bucle ya podemos devolver el valor final, que estará en la variable resultado.

Nótese que, si en un principio, la variable n es 0, no se entrará en el bucle al no ser

Page 21: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

cierta la condición, por lo que pasaría directamente a devolver la variable

resultado, que tiene valor inicial 1 (0! = 1).

2.6. LENGUAJES FUNCIONALES

2.6.1. CONCEPTO MATEMÁTICO DE FUNCIÓN.

Puede ser definida como una correspondencia entre dos variables, una

llamada variable dependiente y otra llamada variable dependiente. Veamos la

siguiente notación:

y = f(x)

Donde:

y: Es la variable dependiente de la función. Se le llama dependiente porque

para que pueda tomar un valor, depende de los valores que pueda tomar la

variable x. También podemos decir que “y esta en función de x”.

x: Es la variable independiente de la función. Se dice que es independiente ya

que puede tomar los valores que quiera y no hay nada que se lo impida; o sea,

tiene independencia.

f: Se puede decir que es el procedimiento o ecuación que tomará a x para

devolverle un valor a y.

Veamos una función muy común:

y = x2 + x

La función anterior tiene a y como variable dependiente y a x como variable

independiente, y el procedimiento es elevar a x (variable independiente) al

cuadrado y sumarle x. Por cada valor que tome x, a y le corresponderá otro.

También podemos tener una función con más de una variable dependiente...

y = x + z – 1 / (w + 3)

En el sistema anterior podemos encontrar que la variable dependiente (en este

caso y) esta en función de 3 variables independientes (en este caso x, z, w).

Generalmente en las matemáticas las variables dependientes están

representadas por la letra y, aunque también las podemos representar con letras

como z, w, ó x, ó g, etc. siempre y cuando sean diferentes de las variables

Page 22: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

independientes; así mismo, la o las variables independientes se pueden

representar de la misma forma, teniendo en cuenta que no deben ser iguales a

las dependientes.

2.6.2. CONCEPTO DE LENGUAJES FUNCIONALES.

Los matemáticos desde hace un buen tiempo están resolviendo problemas

usando el concepto de función. Una función convierte ciertos datos en

resultados. Si supiéramos cómo evaluar una función, usando la computadora,

podríamos resolver automáticamente muchos problemas. Así pensaron algunos

matemáticos, que no le tenían miedo a la máquina, e inventaron los lenguajes

de programación funcionales. Además, aprovecharon la posibilidad que tienen

las funciones para manipular datos simbólicos, y no solamente numéricos, y la

propiedad de las funciones que les permite componer, creando de esta manera,

la oportunidad para resolver problemas complejos a partir de las soluciones a

otros más sencillos. También se incluyó la posibilidad de definir funciones

recursivamente.

Un lenguaje funcional ofrece conceptos que son muy entendibles y

relativamente fáciles de manejar para todos los que no se durmieron en las

clases de matemáticas. El lenguaje funcional más antiguo, y seguramente el

más popular hasta la fecha, es LISP, diseñado por McCarthy en la segunda

mitad de los años 50. Su área de aplicación es principalmente la Inteligencia

Artificial. En la década de los 80 hubo una nueva ola de interés por los

lenguajes funcionales, añadiendo la tipificación y algunos conceptos modernos

de modularización y polimorfismo, como es el caso del lenguaje ML.

Programar en un lenguaje funcional significa construir funciones a partir de las

ya existentes. Por lo tanto es importante conocer y comprender bien las

funciones que conforman la base del lenguaje, así como las que ya fueron

definidas previamente. De esta manera se pueden ir construyendo aplicaciones

cada vez más complejas. La desventaja de este modelo es que resulta bastante

alejado del modelo de la máquina de Von Neumann y, por lo tanto, la

eficiencia de ejecución de los intérpretes de lenguajes funcionales no es

comparable con la ejecución de los programas imperativos precompilados.

Para remediar la deficiencia, se está buscando utilizar arquitecturas paralelas

Page 23: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

que mejoren el desempeño de los programas funcionales, sin que hasta la fecha

estos intentos tengan un impacto real importante.

2.6.3. CATEGORÍAS DE LENGUAJES FUNCIONALES.

Existen dos categorías de lenguajes funcionales: los funcionales puros y los

híbridos, La diferencia entre ambos estriba en que los lenguajes funcionales

híbridos son menos dogmáticos que los puros, al admitir conceptos tomados de

los lenguajes imperativos, como las secuencias de instrucciones o la

asignación de variables. En contraste, los lenguajes funcionales puros tienen

una mayor potencia expresiva, conservando a la vez su transparencia

referencial, algo que no se cumple siempre con un lenguaje funcional híbrido.

Entre los lenguajes funcionales puros, cabe destacar a Haskell y Miranda. Los

lenguajes funcionales híbridos más conocidos son Lisp, Scheme, Ocaml y

Standard ML (estos dos últimos, descendientes del lenguaje ML).

2.6.4. PROBLEMAS DEL MODELO IMPERATIVO

Los programas escritos en lenguajes de programación tradicionales

(imperativo) como Pascal, C, ADA, etc. forman una abstracción de la máquina

de Von-Neumann caracterizada por:

Memoria Principal para almacenamiento de datos y

código máquina.

Unidad Central de Proceso con una serie de registros de

almacenamiento temporal y un conjunto instrucciones de cálculo

aritmético, modificación de registros y acceso a la Memoria Principal.

Los programas imperativos están formados por una serie de datos globales y

un conjunto de instrucciones ó código. Estos dos elementos forman una

abstracción de los datos y código de la memoria principal.

El programador trabaja en un nivel cercano a la máquina lo que le permite

generar programas eficientes. Con esta proximidad aparece, sin embargo, una

dependencia entre el algoritmo y la arquitectura que impide, por ejemplo,

utilizar algoritmos programados para arquitecturas secuenciales en

arquitecturas paralelas.

Page 24: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Los algoritmos escritos en lenguajes imperativos se expresan mediante una

secuencia de instrucciones que modifican el estado de un programa accediendo

a los datos globales de la memoria. En este punto es donde empiezan los

problemas:

Ejemplo

Program prueba;

var flag:boolean;

function f (n: integer):integer;

begin

flag:=not flag;

if flag then f:=n;

else f:=2*n;

end;

........

--Programa principal

begin

flag:=true;

......

write(f(1)); retorna 2

write(f(1)); retorna 1

.......

write(f(1) + f(2)); retorna 4

write(f(2) + f(1)); retorna 5

En el primer caso la expresión f(1) retorna valores diferentes dependiendo de

la secuencia de ejecución y en el segundo no se cumplen propiedades

matemáticas simples tales como la conmutatividad. Estos ejemplos ponen en

evidencia que ciertas características de los lenguajes imperativos tales como la

asignación pueden traer consigo efectos laterales inesperados que oscurecen la

semántica del programa; en consecuencia se hace difícil demostrar que los

programas cumplen con los requerimientos especificados y que estén libres de

errores.

Page 25: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Este y otros problemas son inherentes al modelo computacional utilizado, por

ende una solución factible de ser aplicada puede ser cambiar el modelo

computacional. Entre otras alternativas se encuentran el modelo funcional o

aplicativo cuyo objetivo es describir los problemas mediante funciones

matemáticas sin efectos laterales, y el modelo lógico o declarativo que

describe los problemas mediante relaciones entre objetos o entidades.

2.7. LENGUAJES LÓGICOS (DECLARATIVOS)

Otra forma de razonar para resolver problemas en matemáticas se fundamenta en

la lógica de primer orden. El conocimiento básico de las matemáticas se puede

representar en la lógica en forma de axiomas, a los cuales se añaden reglas

formales para deducir cosas verdaderas (teoremas) a partir de los axiomas. Gracias

al trabajo de algunos matemáticos, de finales de siglo pasado y principios de éste,

se encontró la manera de automatizar computacionalmente el razonamiento lógico

-particularmente para un subconjunto significativo de la lógica de primer orden-

que permitió que la lógica matemática diera origen a otro tipo de lenguajes de

programación, conocidos como lenguajes lógicos. También se conoce a estos

lenguajes, y a los funcionales, como lenguajes declarativos, porque el

programador, parar solucionar un problema, todo lo que tiene que hacer es

describirlo vía axiomas y reglas de deducción en el caso de la programación lógica

y vía funciones en el caso de la programación funcional.

En los lenguajes lógicos se utiliza el formalismo de la lógica para representar el

conocimiento sobre un problema y para hacer preguntas que, si se demuestra que

se pueden deducir a partir del conocimiento dado en forma de axiomas y de las

reglas de deducción estipuladas, se vuelven teoremas. Así se encuentran

soluciones a problemas formulados como preguntas. Con base en la información

expresada dentro de la lógica de primer orden, se formulan las preguntas sobre el

dominio del problema y el intérprete del lenguaje lógico trata de encontrar la

respuesta automáticamente. El conocimiento sobre el problema se expresa en

forma de predicados (axiomas) que establecen relaciones sobre los símbolos que

representan los datos del dominio del problema.

En el caso de la programación lógica, el trabajo del programador se restringe a la

buena descripción del problema en forma de hechos y reglas. A partir de ésta se

Page 26: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

pueden encontrar muchas soluciones dependiendo de como se formulen las

preguntas (metas), que tienen sentido para el problema. Si el programa está bien

definido, el sistema encuentra automáticamente las respuestas a las preguntas

formuladas. En este caso ya no es necesario definir el algoritmo de solución, como

en la programación imperativa, en cambio, lo fundamental aquí es expresar bien el

conocimiento sobre el problema mismo. En programación lógica, al igual que en

programación funcional, el programa, en este caso los hechos y las reglas, están

muy alejados del modelo von Neumann que posee la máquina en la que tienen que

ser interpretados; por lo tanto, la eficiencia de la ejecución no puede ser

comparable con la de un programa equivalente escrito en un lenguaje imperativo.

Sin embargo, para cierto tipo de problemas, la formulación del programa mismo

puede ser mucho más sencilla y natural (para un programador experimentado, por

supuesto).

PROLOG

Prolog, proveniente del francés Programation et Logique, sus orígenes se

remotan a los inicios de la década de los 70 con los trabajos del grupo de A.

Colmerauer en Marsella, Francia. Es un lenguaje de programación lógico e

interpretado, bastante popular en el medio de investigación en Inteligencia

Artificial.

Historia

Se trata de un lenguaje de programación ideado a principios de los años 70

en la universidad de Aix-Marseille por los profesores Alain Colmerauer y

Phillipe Roussel. Inicialmente se trataba de un lenguaje totalmente

interpretado hasta que, a mediados de los 70, David H.D. Warren

desarrolló un compilador capaz de traducir Prolog en un conjunto de

instrucciones de una máquina abstracta denominada Warren Abstract

Machine, o abreviadamente, WAM. Desde entonces Prolog es un lenguaje

semi-interpretado.

Prolog se enmarca en el paradigma de los lenguajes lógicos, lo que lo

diferencia enormemente de otros lenguajes más populares tales como

Fortran, Pascal, C.

Page 27: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Retroseguimiento

En todos los mencionados, las instrucciones se ejecutan normalmente en

orden secuencial, es decir, una a continuación de otra, en el mismo orden

en que están escritas, que sólo varía cuando se alcanza una instrucción de

control (un bucle, una instrucción condicional o una transferencia).

Los programas en Prolog se componen de cláusulas de Horn que

constituyen reglas del tipo "modus ponendo ponens", es decir, "Si es

verdad el antecedente, entonces es verdad el consecuente". No obstante, la

forma de escribir las cláusulas de Horn es al contrario de lo habitual.

Primero se escribe el consecuente y luego el antecedente. El antecedente

puede ser una conjunción de condiciones que se denomina secuencia de

objetivos. Cada objetivo se separa con una coma y puede considerarse

similar a una instrucción o llamada a procedimiento de los lenguajes

imperativos. En Prolog no existen instrucciones de control. Su ejecución se

basa en dos conceptos: la unificación y el backtracking.

Gracias a la unificación, cada objetivo determina un subconjunto de

cláusulas susceptibles de ser ejecutadas. Cada una de ellas se denomina

punto de elección. Prolog selecciona el primer punto de elección y sigue

ejecutando el programa hasta determinar si el objetivo es verdadero o

falso.

En caso de ser falso entra en juego el 'backtracking', que consiste en

deshacer todo lo ejecutado situando el programa en el mismo estado en el

que estaba justo antes de llegar al punto de elección. Entonces se toma el

siguiente punto de elección que estaba pendiente y se repite de nuevo el

proceso. Todos los objetivos terminan su ejecución bien en éxito

("verdadero"), bien en fallo ("falso").

Expresiones

Prolog cuenta con operadores para la unificación y comparación sea con

evaluación o sea simbólica como lo siguiente:

X is Y %unificación con evaluación.

Page 28: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

X = Y %unificación simbólica

X=:=Y %comparación con evaluación

X==Y %comparación simbólica.

Listas

La representación de hechos simples no es lo común en la clasificación de

elementos, sino que se agrupan los elementos de un mismo tipo en una

lista.

Ejemplo:

% Si queremos hallar la longitud de una lista.

% La longitud de una lista vacia es 0.

% La longitud de cualquier lista es la longitud de la cola + 1.

longitud([],0).

longitud([H|T],N):-longitud(T,N0), N is N0 + 1.

?- longitud([a,b,c],L).

3

?- longitud([a,b,c],4).

No

% Si queremos determinar si un elemento es pertenece a una lista.

% El elemento pertenece a la lista si coincide con la cabeza de la lista.

% El elemento pertenece a la lista si es se encuentra en la cola de la lista.

pertenece(X,[X|_]).

pertenece(X,[_|R]):- pertenece(X,R).

?- pertenece(b,[a,b,c]).

Yes

?- pertenece(b,[a,[b,c]]).

No

?- pertenece([b,c],[a,[b,c]]).

Yes

% Si queremos eliminar un elemento de la lista.

% Si X es la cabeza de la lista, la cola T es la lista sin X

% Si X no es la cabeza de la lista, conservamos la cabeza de la lista

% como parte de la respuesta y continuamos eliminando X de la cola T.

Page 29: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

elimina (X,[X|T],T).

elimina (X,[H|T],[H|T1]):- elimina (X,T,T1).

?- elimina(1,[1,2,3,4],R).

R = [2,3,4]

?- elimina(1,R,[2,3]).

R = [1, 2, 3]

R = [2, 1, 3]

R = [2, 3, 1]

% Si queremos calcular la inversa de una lista.

% La inversa de una lista vacia es una lista vacia.

% La inversa de H|T es la inversa de T concatenada con H.

inversa([],[]).

inversa([H|T],L):- inversa(T,R), concatenar(R,[H],L).

?- inversa([a,b,c,d],[d,c,b,a]).

Yes

2.8. LENGUAJES ORIENTADOS A OBJETOS

A mediados de los años 60 se empezó a vislumbrar el uso de las computadoras

para la simulación de problemas del mundo real. Pero el mundo real está lleno de

objetos, en la mayoría de los casos complejos, los cuales difícilmente se traducen a

los tipos de datos primitivos de los lenguajes imperativos. Así es que a dos

noruegos, Dahl y Nygaard, se les ocurrió el concepto de objeto y sus colecciones,

llamadas clases de objetos, que permitieron introducir abstracciones de datos a los

lenguajes de programación. La posibilidad de reutilización del código y sus

indispensables modificaciones, se reflejaron en la idea de las jerarquías de

herencia de clases. A ellos también les debemos el concepto de polimorfismo

introducido vía procedimientos virtuales. Todos estos conceptos fueron

presentados en el lenguaje Simula 67, desde el año 1967. Aunque pensado como

lenguaje de propósito general, Simula tuvo su mayor éxito en las aplicaciones de

simulación discreta, gracias a la clase SIMULATION que facilitaba

considerablemente la programación.

La comunidad informática ha tardado demasiado en entender la utilidad de los

conceptos básicos de Simula 67, que hoy identificamos como conceptos del

Page 30: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

modelo de objetos. Tuvimos que esperar hasta los años 80 para vivir una

verdadera ola de propuestas de lenguajes de programación con conceptos de

objetos encabezada por Smalltalk, C++, Eiffel, Modula-3, Ada 95 y terminando

con Java. La moda de objetos se ha extendido de los lenguajes de programación a

la Ingeniería de Software

La reutilización de clases previamente probadas en distintos sistemas también es

otro punto a favor. Sin embargo, el modelo de objetos, a la hora de ser

interpretado en la arquitectura von Neumann conlleva un excesivo manejo

dinámico de memoria debido a la constante creación de objetos, así como a una

carga de código fuerte causada por la constante invocación de métodos. Por lo

tanto, los programas en lenguajes orientados a objetos siempre pierden en

eficiencia, en tiempo y memoria, contra los programas equivalentes en lenguajes

imperativos. Para consolarnos, los expertos dicen que les ganan en la comprensión

de código.

Características fundamentales de la POO:1. Encapsulamiento: Es la ocultación de información. Significa mantener la

información dentro del objeto y mantenerlo como una caja negra. Puede

ser accedida por métodos.

2. Abstracción: Es la capacidad de aislar y encapsular la información del

diseño y la ejecución. Es la capacidad para identificar atributos y métodos.

Herencia: Es la propiedad que permite a los objetos crearse a partir de

otros objetos.

3. Polimorfismo: Es la capacidad de que diferentes objetos reaccionen de

distinta forma a un mismo mensaje.

2.9. LENGUAJES CON CONCURRENCIA

La necesidad de ofrecer concurrencia en el acceso a los recursos computacionales

se remonta a los primeros sistemas operativos. Mientras que un programa

realizaba una operación de entrada o salida otro podría gozar del tiempo del

procesador para sumar dos números, por ejemplo. Aprovechar al máximo los

recursos computacionales fue una necesidad apremiante, sobre todo en la época en

que las computadoras eran caras y escasas; el sistema operativo tenía que ofrecer

Page 31: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

la ejecución concurrente y segura de programas de varios usuarios, que desde

distintas terminales utilizaban un solo procesador, y así surgió la necesidad de

introducir algunos conceptos de programación concurrente para programar los

sistemas operativos.

Posteriormente, cuando los procesadores cambiaron de tamaño y de precio, se

abrió la posibilidad de contar con varios procesadores en una máquina y ofrecer el

procesamiento en paralelo, es decir, procesar varios programas al mismo tiempo.

Esto dio el impulso a la creación de lenguajes que permitían expresar el

paralelismo. Finalmente, llegaron las redes de computadoras, que también ofrecen

la posibilidad de ejecución en paralelo, pero con procesadores distantes, lo cual

conocemos como la programación distribuida.

Históricamente encontramos en la literatura soluciones conceptuales y

mecanismos tales como: semáforos, regiones críticas, monitores, envío de

mensajes (CSP), llamadas a procedimientos remotos (RPC), que posteriormente se

incluyeron como partes de los lenguajes de programación en Concurrent Pascal,

Modula, Ada, OCCAM, y últimamente en Java.

Uno de los ejemplos más importantes es el modelo de envío de mensajes de CSP

de Hoare, para las arquitecturas paralelas y distribuidas, el cual no solamente

fructificó en una propuesta del lenguaje de programación OCCAM, sino dio

origen a una nueva familia de procesadores, llamados "transputers", que

fácilmente se componen en una arquitectura paralela.

Es difícil evaluar las propuestas existentes de lenguajes para la programación

concurrente, paralela y distribuida. Primero, porque los programadores están

acostumbrados a la programación secuencial y cualquier uso de estos mecanismos

les dificulta la construcción y el análisis de programas. Por otro lado, este tipo de

conceptos en el pasado fue manejado principalmente a nivel de sistemas

operativos, protocolos de comunicación, etcétera, donde la eficiencia era crucial, y

por lo tanto no se utilizaban lenguajes de alto nivel para la programación. Hoy en

día, la programación de sistemas complejos tiene que incluir las partes de

comunicaciones, programación distribuida y concurrencia. Esto lo saben los

creadores de los lenguajes más recientes, que integran conceptos para manejar: los

hilos de control, comunicación, sincronización y no determinismo; el hardware y

las aplicaciones se los exigen.

Page 32: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

2.10. EVOLUCIÓN DE LOS LENGUAJES DE PROGRAMACIÓN

DECLARATIVOS

Gráfico Nº 1: Evolución de los lenguajes de programación Declarativos

Page 33: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

2.11. EVOLUCIÓN DE LOS LENGUAJES DE PROGRAMACIÓN

ORIENTADO A OBJETOS E IMPERATIVOS

Gráfico Nº 2: Evolución de los lenguajes de programación OO e Imperativos

Page 34: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

CAPÍTULO III: CONCEPTOS EN LOS LENGUAJES DE

PROGRAMACIÓN

3.1. ¿QUÉ ES LO QUE CONSTITUYE UN BUEN LENGUAJE?

3.1.1. ATRIBUTOS DE UN BUEN LENGUAJE

Claridad, sencillez y unidad (legibilidad): La sintaxis

del lenguaje afecta la facilidad con la que un programa se puede escribir,

por a prueba, y más tarde entender y modificar.

Ortogonalidad: Capacidad para combinar varias

características de un lenguaje en todas las combinaciones posibles, de

manera que todas ellas tengan significado.

Naturalidad para la aplicación: La sintaxis del

programa debe permitir que la estructura del programa refleje la estructura

lógica subyacente.

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.

Facilidad para verificar programas: La sencillez de la

estructura semántica y sintáctica ayuda a simplificar la verificación de

programas.

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.

Portabilidad de programas

Costo de uso:

1. Costo de ejecución del programa.

2. Costo de traducción de programas.

3. Costo de creación, prueba y uso de programas.

4. Costo de mantenimiento de los programas: costo total del ciclo de vida.

Page 35: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

3.1.2. ESTANDARIZACIÓN DE LOS LENGUAJES

Los estándares son en general de dos clases:

Estándares patentados: Son las definiciones

elaboradas por la compañía que desarrolló el lenguaje y que es su

propietaria.

Estándares de consenso: Se trata de documentos

elaborados por organizaciones con base en un acuerdo entre los

participantes pertinentes. Método principal para asegurar la uniformidad

entre varias implementaciones de un lenguaje. Ejemplo: ANSI, IEEE, ISO,

etc..

3.2. SINTAXIS DE LENGUAJES DE PROGRAMACIÓN

La sintaxis suministra información significativa que se necesita para entender un

programa y proporciona información imprescindible para la traducción del

programa fuente a un programa objeto.

Se necesita algo más que sólo estructuras sintácticas para la plena descripción de

un lenguaje de programación. Otros atributos bajo el término general de

semántica, como el uso de declaraciones, operaciones, control de secuencia y

entornos de refinamiento, afectan a una variable y no siempre están determinados

por reglas de sintaxis.

CRITERIOS GENERALES DE SINTAXIS

El propósito primordial de la sintaxis es proveer una notación para la

comunicación entre el programador y el procesador de lenguajes de programación.

Los detalles de la sintaxis se eligen en gran medida con base en criterios

secundarios, como:

Legibilidad: Un programa es legible si la estructura subyacente del

algoritmo y los datos que el programa representa quedan de manifiesto al

inspeccionar el texto del programa.

Page 36: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Facilidad de escritura: Suele hallarse en conflicto con las

características que facilitan su lectura. Este atributo mejora a través del uso

de estructuras sintácticas concisas y regulares.

Una sintaxis es redundante si comunica el mismo elemento de información en más

de una forma. Cierta redundancia es útil en la sintaxis de lenguajes de

programación porque facilita la lectura del programa y también permite revisar en

busca de errores durante la traducción.

Facilidad de verificación: Tiene relación con la legibilidad y

facilidad de escritura. Se necesitan técnicas que permitan comprobar que el

programa es matemáticamente correcto.

Facilidad de traducción: Los programas deben ser fáciles de

traducir a una forma ejecutable. Está relacionado con las necesidades del

traductor que procesa el programa escrito.

La traducción de los programas se dificulta conforme aumenta el número

de construcciones sintácticas especiales.

Carencia de ambigüedad: Una construcción ambigua permite dos

o más interpretaciones distintas. El problema de ambigüedad surge por lo

común no en la estructura de elementos individuales del programa, sino en

la interacción entre diferentes estructuras (Ej. Condicionales).

3.3. TIPOS DE DATOS

Numéricos: Entero, Real.

Booleano.

Carácter.

Definidos por el usuario: tipos especificados por el usuario como

limitaciones de los básicos.

Enumerados, subrangos, modulares…

Arrays: son tipos con tamaño fijo y todos los elementos del mismo

tipo.

String está definido e muchos lenguajes como un array de caracteres.

Registros: Es una estructura de datos formada por un numero fijo de

componentes de distinto tipo.

Page 37: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Punteros: almacena la dirección de memoria de otro objeto de datos.

Referencia: no se pueden manejar directamente, lo hace el

compilador.

Tipo función: se considera un tipo por poderse incluir en una

expresión, y suele ir acompañado de su descriptor.

3.4. ABSTRACCIÓN

La abstracción nos permite simplificar el análisis y resolución de un problema

separando las características que son relevantes de aquellas que no lo son. La

relevancia dependerá fuertemente del contexto. Un ejemplo típico de abstracción

es una jerarquía de objetos determinada por sus características comunes.

Aunque la abstracción es un concepto general aplicable a cualquier campo

nosotros estamos interesados en la abstracción que proporciona un lenguaje de

programación. En este sentido la aportación más importante ha sido el desarrollo

de los lenguajes de alto nivel, éstos nos permiten utilizar ciertas construcciones de

alto nivel en lugar de una secuencia de instrucciones máquina. Aún así, el nivel de

abstracción proporcionado por un lenguaje de programación resulta insuficiente.

Podemos aumentar el nivel de abstracción haciendo que el lenguaje de

programación incluya mecanismos que permitan construir al usuario sus propias

abstracciones. El mecanismo más común para tal fin es el uso de funciones y

procedimientos, aunque existen otros mecanismos.

Los lenguajes de programación orientados a objetos ofrecen un cada vez más

amplio abanico de estructuras de datos organizadas jerárquicamente (listas, pilas,

colas, etc.) junto con primitivas para manejarlas agrupadas en lo que

habitualmente se conoce como clase, además, el usuario puede definir nuevas

clases

3.5. ABSTRACCIÓN EN PROGRAMACIÓN

Cuando la computación estaba en su infancia, la mayoría de los programas se

escribían en ensamblador por un programador, y no se considerarían como

grandes programas según los estándares de hoy en día. Aún así, en la medida en

que los programas se hicieron más complejos, los programadores encontraron más

Page 38: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

dificultades para recordar toda la información que necesitaban para desarrollar o

eliminar errores de sus programas.

Aunque la introducción de lenguajes de alto nivel resolvió algunas dificultades, al

mismo tiempo incrementó las expectativas de la gente acerca de lo que podría

hacer una computadora, de tal forma que sólo provocó la aparición de un mayor

número de problemas. Así, a medida que se intentaban resolver problemas más

complejos por medio de una computadora, mayor era la tarea que debía desarrollar

el programador, rebasando la capacidad incluso de los mejores programadores. En

consecuencia, comenzaron a proliferar equipos de programadores que trabajaban

conjuntamente para emprender grandes tareas de programación.

Se observó entonces un problema que aún hoy no se ha abordado de forma

completamente satisfactoria: los sistemas de software son sistemas complejos con

un alto grado de interconexión. La interconexión es la dependencia de una parte

del código de otra sección de código.

Surgieron así diversas técnicas y mecanismos para tratar de reducir el problema de

la complejidad. La abstracción es uno de estos mecanismos y es posiblemente el

más importante de todos. El mecanismo de abstracción permite descomponer de

forma productiva un problema mediante el cambio del nivel de detalle a

considerar, pero es algo intangible. Surge por tanto la necesidad de describirla de

alguna forma, la especificación es esta descripción. La abstracción funcional; es

decir, la idea de crear procedimientos y funciones e invocarlos mediante un

nombre, fue uno de los primeros mecanismos de abstracción que se usaron

ampliamente en los lenguajes de programación. Los procedimientos permitían que

las tareas que se ejecutaban varias veces, fueran agrupadas en un lugar para

reutilizarlas, en vez de duplicar el código una y otra vez. Es este tipo de

abstracción lo importante es qué hace la función y no importa cómo lo hace. El

usuario del procedimiento solo necesita conocer la especificación de la abstracción

y puede ignorar el resto de detalles.

3.6. CLASES DE ABSTRACCIÓN

3.6.1. ABSTRACCIÓN DE CONTROL

Page 39: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Hace referencia a los mecanismos necesarios para representar el flujo de

control de un programa, evitando detalles de bajo nivel. Se subdivide en: nivel

de sentencias básicas y a nivel de subprogramas o unidades de programa.

Sentencias condicionales: If/else, alternativa múltiple

(swith).

Sentencias iterativas: For, While y repeat.

Abstracción procedimental

Subprograma: conjunto de líneas de código con cierta

independencia del resto.

Procedimientos: subprogramas que tienen de 0 a n

parámetros, sin tipo, no pueden ser usados en expresiones y pueden

devolver de 0 a n resultados distintos.

Funciones: pueden tener de 0 a n argumentos de entrada,

devuelve solo 1 resultado siempre. Tiene tipo y se puede usar en una

expresión.

Paso de parámetros:

Formas de paso de parámetros:

Por referencia: se pasa la dirección de memoria del

parámetro (E/S).

Por copia:

Copia por valor: se crea una var temporal copiándole el

valor del parámetro.(E)

Copia por resultado: se crea una var local, y al acabar se

devuelve el resultado (S)

Copia por valor-resultado: se crea una var local pasándole

el valor, con la que se trabaja, y al acabar se devuelve el resultado

Formas de asignar los argumentos:

Por posición: se asignan los parámetros formales con los

reales por orden.

Page 40: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Por nombre: en la llamada se añade el nombre del

parámetro formal.

Por defecto: toma un valor por defecto especificado en

compilación si no se le da ninguno.

Ejemplo:

Void ordenar (int a[],int n) el usuario no necesita conocer los detalles de

cómo se realiza el ordenamiento, solo debe suministrar un arreglo y su tamaño

y recibirá el arreglo ordenado (en un orden predeterminado como ascendente)

3.6.2. ABSTRACCIÓN DE DATOS.

Una abstracción de datos (tipo de dato o tipo abstracto de dato) es un nuevo

tipo de dato más un conjunto de operaciones que permiten manipular los

objetos de dicho tipo. En esta definición juega un papel importante el uso de la

palabra objeto en lugar de variable. La diferencia entre ambos conceptos se

explicará más adelante.

La correcta utilización de los tipos abstractos de datos (TADs en lo sucesivo)

en el diseño de programas da lugar a programas de gran modularidad y

calidad:

Son más legibles

Son más fáciles de interpretar

Son más fáciles de modificar

3.7. TIPOS ABSTRACTOS DE DATOS (TADS)

Es una estructura de datos junto a las instrucciones para manejarlo, haciendo

invisible ciertas partes al usuario programador. Permite la asociación de una

representación con sus operaciones concretas en una unidad adecuada de lenguaje

que incorpora los nuevos tipos y el ocultamiento de la representación del nuevo

tipo a las unidades que lo usan.

Page 41: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Tipos genéricos, genericidad: consiste en que las entidades de programa puedan

trabajar con independencia de los tipos de datos concretos. Para usarse hay que

instanciarlos.

3.8. LENGUAJES DE PROGRAMACIÓN Y TADS

La abstracción de datos es una técnica de diseño de programas que promete un

alto grado de modularidad y un desarrollo independiente de la implementación de

dicha abstracción y de la aplicación del programa. Por tratarse de una técnica de

diseño, su utilización es en su mayor parte independiente del lenguaje de

programación, sin embargo, el uso e implementación de TADs con lenguajes de

programación que no los soportan convenientemente puede dar lugar a

deficiencias en algunos de los aspectos siguientes:

Ocultación de la representación. Los lenguajes que no

soportan TADs no pueden chequear el buen uso de la abstracción de datos,

dada la imposibilidad de ocultar a los usuarios de la abstracción la

representación de los objetos

Inicialización de las estructuras de datos. Los lenguajes

que no soportan TADs no disponen de un procedimiento automático de

inicialización de las estructuras de datos que se utilizan para representar a los

objetos del TAD. Esto supone que al principio de los programas que utilicen

un TAD debe invocarse a una acción para inicializar convenientemente dichas

estructuras (operación no relacionada con los objetos

Compilación independiente. En los lenguajes que

soportan TADs, el código de estos se puede separar del código de los

programas de aplicación y compilarlos independientemente. En todo caso, esta

facilidad se tiene en cualquier lenguaje que soporte la compilación

independiente.

Parametrización de tipos. En los lenguajes que no

soportan TADs no se puede parametrizar una definición de tipo con otro tipo;

es decir, no se pueden realizar abstracciones (funcionales o de datos) de tipos

desconocidos.

Page 42: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Abstracciones polimórficas. En los lenguajes que no

soportan TADs no se pueden construir abstracciones que puedan ser utilizadas

por objetos de diferentes tipos.

Los tipos definidos por el usuario no se comportan

como los predefinidos del lenguaje. Así, por ejemplo, un objeto de tipo

Racional no se crea por completo al declararlo siendo necesario realizar una

llamada posterior a la operación Crear_Racional para inicializarlo

convenientemente.

Esta última deficiencia provoca que en un lenguaje de programación que no

soporte TADs puedan existir objetos cuya representación no sea válida sin que

ello sea detectado por el compilador. Esto obliga al usuario a utilizar

escrupulosamente el TAD, o bien, al desarrollador de la abstracción de datos a

realizar implementaciones de éste que tuvieran en cuenta éste hecho.

3.9. LENGUAJES DE PROGRAMACIÓN QUE DEBERÍAS APRENDER

3.9.1. PHP

PHP usa una mezcla entre interpretación y compilación para intentar ofrecer a

los programadores la mejor mezcla entre rendimiento y flexibilidad.

PHP compila para tu codigo una serie de instrucciones (llamadas opcodes)

siempre que estas son accedidas. Estas instrucciones son entonces ejecutadas

una por una hasta que el script termina. Esto es diferente a la manera

convencional de compilacion de lenguajes como C++ donde el código es

compilado a código ejecutable que es despues ejecutado. Php es recompilado

cada vez que se solicita un script. Una ventaja importante de interpretar el

código es que toda la memoria usada por tu código es manejada por PHP, y el

lenguaje automáticamente vacía esta memoria cuando el script finaliza. Esto

significa que tu no tienes que preocuparte de las conexiones a la base de datos,

porque PHP lo hará por ti.

Page 43: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

¿Por qué deberías aprenderlo?

Es uno de los lenguajes de programación más populares, la gran fluidez y

rapidez de sus scripts y su prometedor futuro, desarrollar aplicaciones Webs

utilizando lenguajes como C o COBOL son cosas del pasado.

3.9.2. C#

C# es un lenguaje de propósito general orientado a objetos creado por

Microsoft para su plataforma .NET.

Su sintaxis básica deriva de C/C++ y utiliza el modelo de objetos de la

plataforma .NET el cual es similar al de Java aunque incluye mejoras

derivadas de otros lenguajes. C# fue diseñado para combinar el control a bajo

nivel de lenguajes como C y la velocidad de programación de lenguajes como

Visual Basic.

¿Por qué deberías aprenderlo?

Es una parte esencial de la plataforma .Net, C# combina los mejores elementos

de múltiples lenguajes de amplia difusión como C++, Java, Visual Basic o

Delphi. De hecho, su creador Anders Heljsberg fue también el creador de

muchos otros lenguajes y entornos como Turbo Pascal, Delphi o Visual J++.

La idea principal detrás del lenguaje es combinar la potencia de lenguajes

como C++ con la sencillez de lenguajes como Visual Basic, y que además la

migración a este lenguaje por los programadores de C/C++/Java sea lo más

inmediata posible.

3.9.3. AJAX

AJAX no es un lenguaje exactamente su nombre viene dado por el acrónimo

de Asynchronous JavaScript And XML y es posiblemente la mayor novedad

en cuanto a programación web en estos últimos años.

El corazón de Ajax es el objeto XMLHttpRequest que nos permite realizar una

conexión al servidor y al enviarle una petición y recibir la respuesta que

procesaremos en nuestro código Javascript, estamos hablando del verdadero

motor de Ajax, por ejemplo gracias a este objeto podemos desde una página

HTML leer datos de una web o enviar datos de un formulario sin necesidad de

recargar la página.

¿Por qué deberías aprenderlo?

Page 44: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

La demanda de AJAX no sólo es amplía sino que de calidad debido a la

dificultad de aprendizaje que conlleva, si la herramienta de Microsoft, Atlas,

destinada a la realización de aplicaciones AJAX tiene éxito puede supone un

aumento en la demanda de esta tecnología.

3.9.4. JAVASCRIPT

Se trata de un lenguaje de programación del lado del cliente, porque es el

navegador el que soporta la carga de procesamiento. Gracias a su

compatibilidad con la mayoría de los navegadores modernos, es el lenguaje de

programación del lado del cliente más utilizado.

¿Por qué deberías aprenderlo?

La razón de mayor peso es que es utilizado por millones de páginas webs para

validar formularios, crear cookies, detectar navegadores y mejorar el diseño,

su fácil aprendizaje lo hace un lenguaje muy demandado.

3.9.5. PERL

Perl es la alternativa más popular a PHP, seguramente porque es el lenguaje

más antiguo tambien dentro de las alternativas. En internet nos encontramos

numerosos recursos que utilizan Perl, muchos de las aplicaciones "open

source" requieren tener Perl instalado correctamente. Perl tiene una ventaja y

es que es muy flexible, y tambien tiene un gran cantidad de modulos ya

escritos.

Bien escritos los scripts en Perl se asemejan bastante a PHP. La principal

causa de la sucía apariencia de Perl es por la afición de sus desarrolladores a la

escritura en "una línea" empaquetanto numerosas funcionalidades en una sola

línea de código.

¿Por qué deberías aprenderlo?

La potencía de Perl a la hora de procesar grandes cantidades de datos lo hace

realmente popular a la hora de desarrollar aplicaciones del lado del servidor,

aprender Perl o Php es básico a la hora de desarrollar aplicaciones Web.

Page 45: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

3.9.6. C

Es un lenguaje de "medio nivel" pero con numerosas características de bajo

nivel. Dispone de las estructuras típicas de los lenguajes de alto nivel pero, a

su vez, dispone de construcciones del lenguaje que permiten un control a muy

bajo nivel.

¿Por qué deberías aprenderlo?

Aprender C es básico mientras aprendes C estas aprendiendo conceptos

básicos de lenguajes cómo Java o C#, además no sólo es mas sencillo que

estos últimos sino que comporten gran parte de su sintaxis.

3.9.7. RUBY Y RUBY ON RAILS

Ruby on Rails, también conocido como RoR o Rails es un framework de

aplicaciones web de código abierto escrito en el lenguaje de programación

Ruby. Ruby apareció en el año 1995 y creo que su principal problema había

sido la falta de documentación en otro idioma que no sea japonés. Eso se ha

ido solucionando y crece la popularidad del lenguaje. Su aplicación insignia,

por decirlo de algún modo parece ser RoR. Su mecanismo de gem parece al

CPAN de Perl y al Pear de PHP

¿Por qué deberías aprenderlo?

Simple y funcional, el uso de Active Record de forma eficiente simplifica y

agiliza el desarrollo de forma notable. Al minimizar el trabajo con la base de

datos (escribiendo triggers y procedimientos almacenados) y emplear un único

lenguaje para todo el desarrollo, se consigue acortar los tiempos de desarrollo

(time2market).

3.9.8. ASP

Active Server Pages (ASP) y ASP.NET es un intento de Microsoft para

introducirse en el mercado del desarrollo Web, y viene a ser como su estandar

para su servidor Web, IIS. ASP ha sido atacado por la comunidad open source

desde que este apareció, y dan numerosas razones para ello:

El propietario, una única plataforma, la lentitud...

ASP ha sido implementado en otras plataformas y que cuando esta

funcionando bajo su servidor predeterminado IIS es relativamente rápido.

Page 46: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

¿Por qué deberías aprenderlo?

Simplemente porqué en algunas ocasiones no tienes otra opción debido a la

popularidad que ha alcanzado.

Page 47: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

CAPÍTULO IV: LENGUAJES DE BAJO, MEDIO Y ALTO

NIVEL

4.1. INTRODUCCIÓN

El ordenador sólo entiende un lenguaje conocido como código binario o código

máquina, consistente en ceros y unos. Es decir, sólo utiliza 0 y 1 para codificar

cualquier acción.

Los lenguajes más próximos a la arquitectura hardware se denominan lenguajes de

bajo nivel y los que se encuentran más cercanos a los programadores y usuarios se

denominan lenguajes de alto nivel.

4.2. LENGUAJES DE BAJO NIVEL

Vistos a muy bajo nivel, los microprocesadores procesan exclusivamente señales

electrónicas binarias. Dar una instrucción a un microprocesador supone en

realidad enviar series de unos y ceros espaciadas en el tiempo de una forma

determinada. Esta secuencia de señales se denomina código máquina. El código

representa normalmente datos y números e instrucciones para manipularlos. Un

modo más fácil de comprender el código máquina es dando a cada instrucción un

mnemónico, como por ejemplo STORE, ADD o JUMP. Esta abstracción da como

resultado el ensamblador, un lenguaje de muy bajo nivel que es específico de cada

microprocesador.

Los lenguajes de bajo nivel permiten crear programas muy rápidos, pero que son a

menudo difíciles de aprender. Más importante es el hecho de que los programas

escritos en un bajo nivel son totalmente dependientes de la máquina o de cada

procesador. Si se lleva el programa a otra máquina se debe reescribir el programa

desde el principio. Al estar prácticamente diseñados a medida del hardware,

aprovechan al máximo las características del mismo.

Dentro de este grupo se encuentran:

LENGUAJE MÁQUINA.

ENSAMBLADOR.

Page 48: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

4.2.1. LENGUAJE MÁQUINA.

El lenguaje máquina es el único lenguaje que entiende directamente la

computadora. Por esta razón, su estructura esta totalmente adaptada a los

circuitos de la máquina y muy alejado de la forma de expresión y análisis de

los problemas propia de los humanos. Esto hace que la programación en este

lenguaje resulte tediosa y complicada, requiriéndose un conocimiento

profundo de la arquitectura física del ordenador. Frente a esto, el código

máquina hace posible que el programador utilice la totalidad de los recursos

que ofrece el ordenador, obteniéndose programas muy eficientes (es decir,

que aprovechan al máximo los recursos existentes) en tiempo de ejecución y

en ocupación de memoria.

4.2.2. ENSAMBLADOR.

El lenguaje ensamblador constituye el primer intento de sustitución del

lenguaje máquina por uno más cercano al usado por los humanos. Este

acercamiento a las personas se plasma en las siguientes aportaciones:

Uso de una notación simbólica o nemotécnica para

representar los códigos de operación

direccionamiento simbólico

Se permite el uso de comentarios entre las líneas de

instrucciones, haciendo posible la redacción de programas más legibles.

Aparte de esto él LE presenta la mayoría de los inconvenientes del lenguaje

máquina, como son su repertorio muy reducido de instrucciones, el rígido

formato de instrucciones, la baja potabilidad y la fuerte dependencia del

hardware. Por otro lado mantiene la ventaja del uso óptimo de los recursos

hardware, permitiendo la obtención de un código muy eficiente.

Ese tipo de lenguajes hacen corresponder a cada instrucción en ensamblador

una instrucción en código máquina. Esta transducción es llevada a cabo por

un programa traductor denominado Ensamblador.

Para solventar en cierta medida la limitación que supone poseer un repertorio

de instrucciones, tan reducido, se han desarrollado unos ensambladores

especiales denominados macroensambladores.

Page 49: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Los lenguajes que traducen los macroensambladores disponen de

macroinstrucciones cuya traducción da lugar a varias instrucciones máquina

y no a una sola.

Dado que el lenguaje ensamblador esta fuertemente condicionado por la

arquitectura del ordenador que soporta, los programadores no suelen escribir

programas de tamaño considerable en ensamblador. Mas bien usan este

lenguaje para afinar partes importantes de programas escritos en lenguajes de

más alto nivel.

Hay un distinto Lenguaje de Máquina (y, por consiguiente, un distinto

Lenguaje Ensamblador) para cada CPU. Por ejemplo, podemos mencionar

tres lenguajes completamente diferentes, que sin embargo vienen de la

aplicación de los conceptos anteriores:

Lenguaje Ensamblador de la familia Intel 80x86

Lenguaje Ensamblador de la familia Motorola 68000

Lenguaje Ensamblador del procesador POWER, usado en las

IBM RS/6000.

Tenemos 3 fabricantes distintos, compitiendo entre sí y cada uno aplicando

conceptos distintos en la manufactura de sus procesadores, su arquitectura y

programación; todos estos aspectos, influyen en que el lenguaje de máquina

y ensamblador cambie bastante.

A) VENTAJAS DEL LENGUAJE ENSAMBLADOR

Una vez que hemos visto la evolución de los lenguajes, cabe preguntarse:

¿En estos tiempos "modernos", para qué quiero el Lenguaje

Ensamblador?

El proceso de evolución trajo consigo algunas desventajas, que ahora

veremos como las ventajas de usar el Lenguaje Ensamblador, respecto a

un lenguaje de alto nivel:

1. Velocidad

El proceso de traducción que realizan los intérpretes, implica un

proceso de cómputo adicional al que el programador quiere realizar.

Por ello, nos encontraremos con que un intérprete es siempre más

Page 50: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

lento que realizar la misma acción en Lenguaje Ensamblador,

simplemente porque tiene el costo adicional de estar traduciendo el

programa, cada vez que lo ejecutamos.

De ahí nacieron los compiladores, que son mucho más rápidos que

los intérpretes, pues hacen la traducción una vez y dejan el código

objeto, que ya es Lenguaje de Máquina, y se puede ejecutar muy

rápidamente. Aunque el proceso de traducción es más complejo y

costoso que el de ensamblar un programa, normalmente podemos

despreciarlo, contra las ventajas de codificar el programa más

rápidamente.

Sin embargo, la mayor parte de las veces, el código generado por un

compilador es menos eficiente que el código equivalente que un

programador escribiría. La razón es que el compilador no tiene tanta

inteligencia, y requiere ser capaz de crear código genérico, que sirva

tanto para un programa como para otro; en cambio, un programador

humano puede aprovechar las características específicas del

problema, reduciendo la generalidad pero al mismo tiempo, no

desperdicia ninguna instrucción, no hace ningún proceso que no sea

necesario.

Para darnos una idea, en una PC, y suponiendo que todos son buenos

programadores, un programa para ordenar una lista tardará cerca de

20 veces más en Visual Basic (un intérprete), y 2 veces más en C (un

compilador), que el equivalente en Ensamblador.

Por ello, cuando es crítica la velocidad del programa, Ensamblador se

vuelve un candidato lógico como lenguaje.

Ahora bien, esto no es un absoluto; un programa bien hecho en C

puede ser muchas veces más rápido que un programa mal hecho en

Ensamblador; sigue siendo sumamente importante la elección

apropiada de algoritmos y estructuras de datos. Por ello, se

recomienda buscar optimizar primero estos aspectos, en el lenguaje

que se desee, y solamente usar Ensamblador cuando se requiere más

optimización y no se puede lograr por estos medios.

Page 51: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

2. Eficiencia de tamaño

Por las mismas razones que vimos en el aspecto de velocidad, los

compiladores e intérpretes generan más código máquina del

necesario; por ello, el programa ejecutable crece. Así, cuando es

importante reducir el tamaño del ejecutable, mejorando el uso de la

memoria y teniendo también beneficios en velocidad, puede convenir

usar el lenguaje Ensamblador. Entre los programas que es crítico el

uso mínimo de memoria, tenemos a los virus y manejadores de

dispositivos (drivers). Muchos de ellos, por supuesto, están escritos

en lenguaje Ensamblador.

3. Flexibilidad

Las razones anteriores son cuestión de grado: podemos hacer las

cosas en otro lenguaje, pero queremos hacerlas más eficientemente.

Pero todos los lenguajes de alto nivel tienen limitantes en el control;

al hacer abstracciones, limitan su propia capacidad. Es decir, existen

tareas que la máquina puede hacer, pero que un lenguaje de alto nivel

no permite. Por ejemplo, en Visual Basic no es posible cambiar la

resolución del monitor a medio programa; es una limitante, impuesta

por la abstracción del GUI Windows. En cambio, en ensamblador es

sumamente sencillo, pues tenemos el acceso directo al hardware del

monitor.

Resumiendo, la flexibilidad consiste en reconocer el hecho de que

Todo lo que puede hacerse con una máquina, puede hacerse en el

lenguaje ensamblador de esta máquina; los lenguajes de alto nivel

tienen en una u otra forma limitante para explotar al máximo los

recursos de la máquina.

Page 52: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

B) DESVENTAJAS DEL LENGUAJE ENSAMBLADOR

Por otro lado, al ser un lenguaje más primitivo, el Ensamblador tiene

ciertas desventajas respecto a los lenguajes de alto nivel:

1. Tiempo de programación.

Al ser de bajo nivel, el Lenguaje Ensamblador requiere más

instrucciones para realizar el mismo proceso, en comparación con un

lenguaje de alto nivel. Por otro lado, requiere de más cuidado por

parte del programador, pues es propenso a que los errores de lógica

se reflejen más fuertemente en la ejecución.

Por todo esto, es más lento el desarrollo de programas comparables

en Lenguaje Ensamblador que en un lenguaje de alto nivel, pues el

programador goza de una menor abstracción.

2. Programas fuente grandes

Por las mismas razones que aumenta el tiempo, crecen los programas

fuentes; simplemente, requerimos más instrucciones primitivas para

describir procesos equivalentes. Esto es una desventaja porque

dificulta el mantenimiento de los programas, y nuevamente reduce la

productividad de los programadores.

3. Peligro de afectar recursos inesperadamente

Tenemos la ventaja de que todo lo que se puede hacer en la máquina,

se puede hacer con el Lenguaje Ensamblador (flexibilidad). El

problema es que todo error que podamos cometer, o todo riesgo que

podamos tener, podemos tenerlo también en este Lenguaje. Dicho de

otra forma, tener mucho poder es útil pero también es peligroso.

En la vida práctica, afortunadamente no ocurre mucho; sin embargo,

al programar en este lenguaje verán que es mucho más común que la

máquina se "cuelgue", "bloquee" o "se le vaya el avión"; y que se

reinicialize. ¿Por qué?, porque con este lenguaje es perfectamente

posible (y sencillo) realizar secuencias de instrucciones inválidas,

que normalmente no aparecen al usar un lenguaje de alto nivel.

Page 53: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

En ciertos casos extremos, puede llegarse a sobreescribir información

del CMOS de la máquina (no he visto efectos más riesgosos); pero, si

no la conservamos, esto puede causar que dejemos de "ver" el disco

duro, junto con toda su información.

4. Falta de portabilidad

Como ya se mencionó, existe un lenguaje ensamblador para cada

máquina; por ello, evidentemente no es una selección apropiada de

lenguaje cuando deseamos codificar en una máquina y luego llevar

los programas a otros sistemas operativos o modelos de

computadoras. Si bien esto es un problema general a todos los

lenguajes, es mucho más notorio en ensamblador: yo puedo reutilizar

un 90% o más del código que desarrollo en "C", en una PC, al

llevarlo a una RS/6000 con UNIX, y lo mismo si después lo llevo a

una Macintosh, siempre y cuando esté bien hecho y siga los

estándares de "C", y los principios de la programación estructurada.

En cambio, si escribimos el programa en Ensamblador de la PC, por

bien que lo desarrollemos y muchos estándares que sigamos,

tendremos prácticamente que reescribir el 100 % del código al

llevarlo a UNIX, y otra vez lo mismo al llevarlo a MAC.

4.3. LENGUAJES DE MEDIO NIVEL

Un lenguaje intermedio se puede definir como una manera de representar

procedimientos y estructuras de datos que sirva como entrada para una MV

(Maquina Virtual) 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.

Para considerar el papel de los lenguajes intermedios y sus ventajas y desventajas,

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,

es decir, la conversión de cada instrucción del lenguaje a código máquina y su

ejecución, una por una, 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

Page 54: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

lenguaje de alto nivel que está siendo interpretado. Y típicamente, 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. Hay ventajas y desventajas en cada

manera de convertir los lenguajes de alto nivel a código máquina, que se pueden

resumir así:

Compilación

Ventajas1.

No hay que repetir la conversión de la misma instrucción a código maquina cada vez que aparece

2. Los programas corren muy rápido

Desventajas1. Perdida de claridad e información sobre el programa

2. Dificultad en localizar la fuente exacta de error

Ejemplo ADA, C , C++, FORTRAN, Pascal

Interpretación

Ventajas1.

No hay pérdida de claridad ni de información sobre un programa ni sobre donde están los errores.

2.No hay que decodificar código que no se va a ejecutar

Desventajas 1.Los programas corren mucho mas lento – se paga el coste de decodificar cada instrucción

Ejemplo HTML, Lisp , ML, Perl, Postscrip, Smalltalk

Estos dos casos representan los dos extremos porque existe también lo que se

llama la compilación parcial, que es una mezcla de los dos enfoques, 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.

Como puede imaginarse, esta técnica combina las ventajas y desventajas de los

dos enfoques anteriores. Un ejemplo de esta combinación existe en el lenguaje de

programación Java y su entorno.

Como se puede ver en los cuadros superiores, 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. La principal ventaja del lenguaje intermedio en este caso

Page 55: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

es su proximidad al nivel del código máquina, en el sentido de que supone menos

trabajo a la hora de ejecutarlo y, por lo tanto, los programas corren más

rápidamente que los puramente interpretados.

Además del papel de los lenguajes intermedios en la compilación parcial, se puede

destacar su papel en la compilación estándar. Como ejemplo se puede considerar

C como lenguaje intermedio para un lenguaje compilado nuevo. Si el autor de un

nuevo lenguaje decide utilizar C, por ejemplo, como su lenguaje intermedio, sólo

tendrá que implementar una MV para convertir el código fuente de su lenguaje a

C, ahorrando mucho trabajo.

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í).

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, características de

memoria o rendimiento se pueden añadir librerías C customizadas sin grandes

problemas).

Las posibilidades disponibles para mapear estructuras

intermedias del nuevo lenguaje a estructuras de datos de C.

Y las desventajas son:

La depuración es muy difícil porque, entre otras cosas, 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.

Las características de rendimiento y eficiencia del lenguaje

están determinadas por el compilador C.

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, por lo

que habrá una pérdida de eficiencia en el programa resultante (como, por

ejemplo, ocurre en la mayoría de las ocasiones en que se compilan estructuras

Page 56: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

de Prolog a C – sólo se puede expresar iteración en Prolog utilizando

recursión).

4.4. LENGUAJES DE ALTO NIVEL

El avance en el desarrollo de "compiladores" e "intérpretes" (los dos tipos de

programas traductores) ha sido por lo tanto fundamental en el desarrollo de los

lenguajes de "3º generación" cuyas ventajas además de la facilidad de aprendizaje

y lectura/escritura son las facilidades de corrección, transformación y conversión

de un lenguaje a otro.

Los lenguajes de alto nivel tienen normalmente las características de

“Transportabilidad”. Es decir, están implementadas sobre varias maquinas de

forma que un programa puede ser fácilmente “Transportado” (Transferido) de una

maquina a otra sin una revisión sustancial. En ese sentido se llama

"Independientes de la maquina".

Los lenguajes de “Alto Nivel” son los más utilizados como lenguaje de

programación. Aunque no son fundamentalmente declarativos, estos lenguajes

permiten que los algoritmos se expresen en un nivel y estilo de escritura

fácilmente legible y comprensible por otros programadores.

Los lenguajes de alto nivel son normalmente fáciles de aprender porque están

formados por elementos de lenguajes naturales, como el inglés. En BASIC, el

lenguaje de alto nivel más conocido, los comandos como "IF CONTADOR = 10

THEN STOP" pueden utilizarse para pedir a la computadora que pare si

CONTADOR es igual a 10.

Están dirigidos a solucionar problemas mediante el uso de EDD's (Estructuras

Dinámicas de Datos: Son estructuras que pueden cambiar de tamaño durante la

ejecución del programa. Nos permiten crear estructuras de datos que se adapten a

las necesidades reales de un programa).

Estos lenguajes permiten al programador olvidarse por completo del

funcionamiento interno de la maquina/s para la que están diseñando el programa.

Tan solo necesitan un traductor que entiendan el código fuente como las

características de la maquina.

Suelen usar tipos de datos para la programación y hay lenguajes de propósito

general (cualquier tipo de aplicación) y de propósito especifico (como FORTRAN

para trabajos científicos).

Page 57: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Ejemplos de estos lenguajes de alto nivel son PASCAL, APL y FORTRAN (para

aplicaciones científicas), COBOL (para aplicaciones de procesamiento de datos),

SNOBOL (para aplicaciones de procesamiento de textos), LISP y PROLOG (para

aplicaciones de inteligencia artificial), C y ADA (para aplicaciones de

programación de sistemas) y PL/I (para aplicaciones de propósitos generales) .

4.5. GENERADORES DE APLICACIONES ó 4º NIVEL

Posteriormente, usando estos lenguajes, se han redactado programas destinados a

facilitar un número variado de operaciones en campos de aplicación específicos

como simulación de fenómenos físicos, manipulación de datos estadísticos, etc.

Los más avanzados y flexibles de estos programas son las planillas electrónicas u

hojas de cálculo y los programas de administración de archivos o bases de datos

Dados que tales aplicaciones no "hacen nada" sin que el usuario defina ciertas

estructuras y ciertas operaciones, pueden ser consideradas como "generadores" de

aplicaciones, aunque este nombre se reserva habitualmente para niveles más

avanzados en que los usuarios pueden generar sistemas muy diferentes unos de

otros, con "herramientas" que se parecen a lenguajes de programación. Estas

herramientas conforman los lenguajes de cuarto nivel que son por esencia

"programas para crear programas" con una finalidad específica, como el "CASE"

destinado a facilitar el trabajo de los analistas de sistemas.

Page 58: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

CAPÍTULO V: ELEMENTOS DE UN LENGUAJE DE

PROGRAMACIÓN

5.1. ELEMENTOS SINTÁCTICOS DE UN LENGUAJE

El estilo sintáctico general de un lenguaje está dado por la selección de diversos

elementos sintácticos básicos. Los más destacados son:

Conjunto de caracteres: La elección del conjunto de caracteres es la

primera que se hace al proyectar una sintaxis de lenguaje. Se usan palabras de

8 bits aunque cada vez más se consideran las representaciones de 16 bits

(65.536 caracteres diferentes).

Identificadores: La sintaxis básica para identificadores, una cadena

de letras y dígitos que comienzan con una letra, tiene amplia aceptación. Las

variaciones entre lenguajes se encuentra entre los signos de puntuación

admitidos (“.” , ”,” , ”-“, “_”...).

Símbolos de operadores: Casi todos los lenguajes emplean los

caracteres especiales “+” y “-“ para representar las dos operaciones

aritméticas básicas. También adoptan alguna combinación y utilización de

caracteres especiales para ciertos operadores.

Palabras clave y palabras reservadas: Una palabra clave es un

identificador que se usa como una parte fija de la sintaxis de un enunciado (ej.

IF). El análisis sintáctico durante la traducción se facilita usando palabras

reservadas. La adicción de una nueva palabra reservada al lenguaje significa

que todo programa antiguo que utilice ese identificador como nombre de

variable (u otro nombre) ya no es sintácticamente correcto.

Palabras pregoneras: Son palabras opcionales que se insertan

en los enunciados para mejorar la legibilidad.

Page 59: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

Comentarios: Ayudan a documentar el programa.

Espacios en blanco: Sus regla varían entre los lenguajes.

Delimitadores y corchetes: Un delimitador es un elemento

sintáctico que se usa simplemente para señalar el principio o el final de

alguna unidad sintáctica, como un enunciado o expresión. Se pueden usar

simplemente para mejorar la legibilidad o simplificar el análisis sintáctico.

Formatos de campos libres y fijos: Una sintaxis es de campo fijo si

los enunciados de programa se pueden escribir en cualquier parte de un

renglón de entrada sin que importe la posición sobre el renglón o las

interrupciones entre renglones. Una sintaxis de campo fijo utiliza la posición

sobre un renglón de entrada para transmitir información.

Expresiones: Son los bloques sintácticos de construcción a partir de

los cuales se construyen enunciados (y a veces programas).

Enunciados: Constituyen el componente sintáctico más destacado

en los lenguajes imperativos. Su sintaxis tiene un efecto decisivo sobre la

regularidad, legibilidad y facilidad de escritura generales del lenguajes.

5.2. TIPOS DE DATOS

Un tipo de datos es una clase de objetos de datos ligados a un conjunto de

operaciones para crearlos y manipularlos.

Todo lenguaje tiene un conjunto de tipos primitivos de datos que están

integrados el lenguaje. Además, un lenguaje puede proveer recursos que permitan

al programador definir nuevos tipos de datos.

Los elementos básicos de una especificación de un tipo de datos son:

A. Los atributos que distinguen objetos de datos de ese tipo.

B. Los valores que los objetos de datos de ese tipo puede tener, y

Page 60: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

C. Las operaciones que definen las posibles manipulaciones de objetos de datos

de ese tipo.

Los elementos básicos de la implementación de un tipo de datos son:

A. La representación de almacenamiento.

B. La manera en que las operaciones definidas para el tipo de datos se representan

en términos de algoritmos o procedimientos particulares que manipulan la

representación de almacenamiento elegida para los objetos de datos.

5.3. NOTACIONES DE EXPRESIONES

El operador binario se aplica a los operandos. En notación infija, un operador

binario se coloca entre sus operandos, como en la expresión a + b. Otras opciones

son la notación prefija (polaca) , en la cual el operador aparece primero, como en

+ab , y la notación postfija (polaca inversa) en la cual el operador se escribe al

final, como en ab+.

 Los paréntesis no son necesarios en notación prefija o postfija, debido a que los

operandos de cada operador pueden encontrarse sin peligro de ambigüedad.

Ejemplo: ( X + Y ) * Z

 Notación Prefija: [ + XY ] * Z

* + XYZ

 

Notación Postfija: [ XY +] * Z

XY + Z *

5.4. PROPIEDAD ASOCIATIVA Y PRECEDENCIA

Convención Tradicional.

 

↑ Exponenciación

* , / Multiplicación, división

+ , - Suma, resta

Page 61: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

5.5. REPRESENTACIÓN DE ÁRBOL PARA EXPRESIONES

Ejemplo. INFIJA : b * b - 4 * a * c

PREFIJA : - * b b * * 4 a c

  POSTFIJA : b b * 4 a * c * -

Árbol de sintaxis abstracta

5.6. EVALUACIÓN DE EXPRESIONES

5.6.1. EVALUACIÓN MEDIANTE LA RECONSTRUCCIÓN DE UN ÁRBOL.

7 * 7 - 4 * 2 * 3

Page 62: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

5.6.2. EVALUACIÓN MEDIANTE UNA PILA

1. Traduzca a notación postfija la expresión que se evaluará.

2. Recorra la notación postfija de izquierda a derecha.

a) Al encontrar una constante introduzca su valor a la pila

b) Al encontrar un operador binario extraiga dos valores de la pila,

aplique el operador a esos valores e introduzca el resultado en la pila.

3. Después de recorrer toda la notación postfija, el valor de la expresión se encuentra en el tope de la pila.

Ejemplo:

Expresión Pila auxiliar Comentario 77*42*3*- 7 Introduzca 7 7*42*3*- 7 7 Introduzca 7 *42*3*- 49 Multiplique 42*3*- 49 4 Introduzca 4 2*3*- 49 4 2 Introduzca 2 *3*- 49 8 Multiplique 3*- 49 8 3 Introduzca 3 *- 49 24 Multiplique - 25 Reste

A) Algoritmo para transformar una notación infija a postfija.

Paréntesis : ( ) Mayor prioridad

Potenciación : ↑

Multiplicación , División : * , /

Suma , Resta : + , -

 Descripción Solución:

1. La expresión se va leyendo carácter a carácter, los operandos pasan

directamente a formar parte de la expresión en postfija.

2. Los operadores se meten en la pila siempre que esta este vacía o bien

siempre que tengan mayor prioridad que el operador cima de la pila (o

bien igual si es la máxima prioridad). Si la prioridad es menor o igual

Page 63: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

se saca el elemento cima de la pila y se vuelve a hacer la comparación

con el elemento cima.

3. Los paréntesis izquierdos siempre se meten en la pila con la mínima

prioridad. Cuando se lee un paréntesis derecho, hay que sacar todos los

operadores de la pila pasando a formar parte de la expresión postfija,

hasta llegar a un paréntesis izquierdo, el cual se elimina, ya que los

paréntesis no forman parte de la expresión postfija.

4. El algoritmo termina cuando no hay más caracteres en la expresión y

la pila esta vacía.

Ejemplo:

A * ( B + C - ( D / E ↑ F ) - G ) – H

caracter leído Expresión Estado de la pila

A*(B+C-(D/E↑F)-G)-H

AAAABABABCABC+AB C+AB C+ DAB C+ DAB C+ D EAB C+ D EAB C+ D E FAB C+ D E F ↑ /AB C+ D E F ↑ / -AB C+ D E F ↑ / - GAB C+ D E F ↑ / - G-AB C+ D E F ↑ / - G- *AB C+ D E F ↑ / - G- *HAB C+ D E F ↑ / - G- * H -

**(*(*(+*(+*(-*(-(*(-(*(-( /*(-( /*(-( / ↑*(-( / ↑*(-*(-*(-*--

En la descripción realizada, se observa que el paréntesis izquierdo tiene la

máxima prioridad fuera de la pila, es decir, en la notación infija; sin embargo,

cuando esta dentro de la pila la prioridad es mínima.

De igual forma, para tratar el hecho de que varios operadores de

potenciación son evaluados de izquierda a derecha, este operador tendrá mayor

prioridad cuando no esta metido en la pila que el mismo pero metido en la pila.

Page 64: HISTORIA DE LOS LENGUAJES DE PROGRAMACION

B) Tabla de prioridades.

Operador Prioridad dentro de la pila Prioridad fuera

de la pila

↑ 3 4

* , / 2 2

+ , - 1 1

( 0 5

C) Algoritmo (pseudocódigo)

1. Obtener caracteres de la expresión y repetir pasos 2 al 4 para cada

carácter

2. Si es operando, pasarlo a la expresión postfija

3. Si es operador

3.1. Si la pila esta vacía meterlo en la pila. Repetir a partir de 1.

3.2. Si la pila no esta vacía.

Si la prioridad del operador leído es mayor que la prioridad del

operador cima de la pila, meterlo en la pila

y repetir a partir de 1.

Si la prioridad del operador es menor o igual que la prioridad del

operador de la cima, sacar de la cima y

pasarlo a la expresión postfija, volver a 3.

4. Si es paréntesis derecho

4.1. Sacar cima de la pila y pasarlo a la expresión postfija

4.2. Si nueva cima es paréntesis izquierdo, suprimir elemento cima.

4.3. Si cima no es paréntesis izquierdo, volver a 4.1

4.4. Volver a partir de 1.

5. Si quedan elementos en la pila, pasarlos a la expresión postfija

6. Fin del algoritmo.