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.
En
esta investigación, intentaremos clarificar estas distinciones
tratando diferentes lenguajes de programación en el contexto
de cada área de aplicación diferente. 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.
Por ejemplo, la universidad de Waterloo desarrolla compiladores
para FORTRAN Y PASCAL, los cuales son útiles en un entorno
de programación de estudiantes debido a su superior capacidad
de diagnostico y velocidad de compilación.
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. Además, hay cuatro niveles distintos
de lenguaje de programación.
Los
"Lenguajes Declarativos" son los mas 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". Ejemplos
de estos lenguajes son los lenguajes estadísticos como SAS
y SPSS y los lenguajes de búsqueda en base de datos, como
NATURAL e IMS. Estos lenguajes se desarrollaron con la idea
de que los profesionales pudieran asimilar mas rápidamente
el lenguaje y usarlo en su trabajo, sin necesidad de programadores
o practicas de programación.
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. Además, 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". 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) .
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. Sin embargo, es necesario un
conocimiento de la arquitectura mecánica subyacente para
realizar una programación efectiva en cualquiera de estos
niveles lenguajes.
Los
siguiente tres segmentos del programa equivalentes exponen
las distinciones básicas entre lenguajes maquina, ensambladores
de alto nivel:
Como
muestra este ejemplo, a mas bajo nivel de lenguaje mas cerca
esta de las características de un tipo e maquina particular
y mas alejado de ser comprendido por un humano ordinario.
Hay también una estrecha relación ( correspondencia 1:1
) entre las sentencias en lenguaje ensamblador y sus formas
en lenguaje maquina codificada. La principal diferencia
aquí es que los lenguajes ensambladores se utilizan símbolos
(X,Y,Z,A para " sumar", M para "multiplicar"), mientras
que se requieren códigos numéricos (OC1A4, etc.) para que
lo comprenda la maquina.
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.
La
compilación es, en general, un proceso mas eficiente que
la interpretación para la mayoría de los tipos de maquina.
Esto se debe principalmente a que las sentencias dentro
de un "bucle" deben ser reinterpretadas cada vez que se
ejecutan por un interprete. Con un compilador. Cada sentencia
es interpretada y luego traducida a lenguaje maquina solo
una vez.
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 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:
- Orientados
a Objetos.
- Imperativa
: Entrada, procesamiento y salidas de Datos.
- Funcional
: "Funciones", los datos son funciones, los resultados
pueden ser un valor o una función.
- Lógico
: {T,F} + operaciones lógicos (Inteligencia Artificial).
- Concurrente
: Aún esta en proceso de investigación.
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 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. Para los lectores que estén
interesados en conocer con mas detalle la historia de los
lenguajes de programación recomendamos las actas de una
recién conferencia (1981) sobre este tema, editadas por
Richard Wexelblat. Vemos que FORTRAN I es un ascendente
directo de FORTRAN II, mientras que FORTRAN, COBOL, ALGO
60, LISP, SNOBOL y los lenguajes ensambladores, influyeron
en el diseño de PL/I.
También
varios lenguajes están prefijados por las letras ANS. 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.