ALGOL 68 (abreviatura de Lenguaje Algorítmico 1968 ) es un lenguaje de programación imperativo que fue concebido como sucesor del lenguaje de programación ALGOL 60 , diseñado con el objetivo de un alcance de aplicación mucho más amplio y una sintaxis y semántica definidas más rigurosamente.
La complejidad de la definición del lenguaje, que abarca varios cientos de páginas llenas de terminología no estándar, dificultó la implementación del compilador y se dijo que "no tenía implementaciones ni usuarios". Esto era sólo parcialmente cierto; ALGOL 68 encontró uso en varios nichos de mercado, especialmente en el Reino Unido , donde era popular en las máquinas de International Computers Limited (ICL), y en funciones de enseñanza. Fuera de estos campos, su uso fue relativamente limitado.
Sin embargo, las contribuciones de ALGOL 68 al campo de la informática han sido profundas, de amplio alcance y duraderas, aunque muchas de estas contribuciones solo se identificaron públicamente cuando reaparecieron en lenguajes de programación desarrollados posteriormente. Muchos lenguajes se desarrollaron específicamente como respuesta a la complejidad percibida del lenguaje, siendo el más notable Pascal , o fueron reimplementaciones para funciones específicas, como Ada .
Muchos lenguajes de la década de 1970 trazan su diseño específicamente a ALGOL 68, seleccionando algunas características y abandonando otras que se consideraban demasiado complejas o fuera del alcance de determinadas funciones. Entre ellos se encuentra el lenguaje C , que recibió la influencia directa de ALGOL 68, especialmente por su tipado fuerte y sus estructuras. La mayoría de los lenguajes modernos trazan al menos parte de su sintaxis a C o Pascal y, por lo tanto, directa o indirectamente a ALGOL 68.
Las características de ALGOL 68 incluyen sintaxis basada en expresiones, tipos y estructuras declarados por el usuario/uniones etiquetadas, un modelo de referencia de variables y parámetros de referencia, segmentación de cadenas, matrices y arreglos, y simultaneidad.
ALGOL 68 fue diseñado por el Grupo de Trabajo 2.1 sobre Cálculos y Lenguajes Algorítmicos de la Federación Internacional de Procesamiento de la Información (IFIP) . El 20 de diciembre de 1968, el lenguaje fue adoptado formalmente por el grupo y luego aprobado para su publicación por la Asamblea General de la IFIP.
ALGOL 68 se definió utilizando un formalismo , una gramática formal de dos niveles , inventada por Adriaan van Wijngaarden . Las gramáticas de Van Wijngaarden utilizan una gramática libre de contexto para generar un conjunto infinito de producciones que reconocerán un programa ALGOL 68 en particular; en particular, pueden expresar el tipo de requisitos que en muchos otros estándares técnicos de lenguajes de programación se etiquetan como semántica , y deben expresarse en prosa de lenguaje natural propensa a la ambigüedad, y luego implementarse en compiladores como código ad hoc adjunto al analizador de lenguaje formal.
ALGOL 68 fue el primer (y posiblemente uno de los últimos) lenguaje importante para el que se realizó una definición formal completa antes de su implementación.
CHA Koster [8]
Los principales objetivos y principios de diseño de ALGOL 68:
ALGOL 68 ha sido criticado, sobre todo por algunos miembros de su comité de diseño, como CAR Hoare y Edsger Dijkstra , por abandonar la simplicidad de ALGOL 60 , convertirse en un vehículo para ideas complejas o excesivamente generales y hacer poco para facilitar la tarea del escritor del compilador , en contraste con contemporáneos deliberadamente simples (y competidores) como C , S-algol y Pascal .
En 1970, ALGOL 68-R se convirtió en el primer compilador funcional para ALGOL 68.
En la revisión de 1973 se omitieron ciertas características, como los procedimientos , los gommas [13] y los límites formales . [14] Véase el lenguaje del informe no revisado.r0
Aunque las agencias de defensa europeas (en Gran Bretaña el Royal Signals and Radar Establishment (RSRE)) promovieron el uso de ALGOL 68 por sus esperadas ventajas en materia de seguridad, la parte estadounidense de la alianza OTAN decidió desarrollar un proyecto diferente, el lenguaje Ada , haciendo obligatorio su uso para los contratos de defensa estadounidenses.
ALGOL 68 también tuvo una influencia notable en la Unión Soviética , cuyos detalles se pueden encontrar en el artículo de Andrey Terekhov de 2014: "ALGOL 68 and Its Impact on the URSS and Russian Programming", [15] y "Алгол 68 и его влияние" . на программирование в СССР и России". [16]
Steve Bourne , que formaba parte del comité de revisión de ALGOL 68, llevó algunas de sus ideas a su shell Bourne (y, por tanto, a los shells Unix descendientes como Bash ) y a C (y, por tanto, a sus descendientes como C++ ).
La historia completa del proyecto se puede encontrar en A History of ALGOL 68 de CH Lindsey . [17] [18]
Para un tratamiento completo del lenguaje, consulte "Programming ALGOL 68 Made Easy" [19] del Dr. Sian Mountbatten, o "Learning ALGOL 68 Genie" [20] de Marcel van der Veer, que incluye el informe revisado.
ALGOL 68, como su nombre lo indica, es una continuación del lenguaje ALGOL que se formalizó por primera vez en 1960. Ese mismo año, la Federación Internacional para el Procesamiento de la Información (IFIP) formó y comenzó el Grupo de Trabajo sobre ALGOL, o WG2.1. Este grupo publicó una especificación ALGOL 60 actualizada en Roma en abril de 1962. En una reunión de seguimiento en marzo de 1964, se acordó que el grupo debería comenzar a trabajar en dos estándares de seguimiento, ALGOL X , que sería una redefinición del lenguaje con algunas adiciones, y un ALGOL Y , que tendría la capacidad de modificar sus propios programas al estilo del lenguaje LISP . [21]
La primera reunión del grupo ALGOL X se celebró en la Universidad de Princeton en mayo de 1965. Un informe de la reunión destacó dos temas con amplio apoyo: la introducción de la tipificación fuerte y el interés en los conceptos de Euler de "árboles" o "listas" para manejar colecciones. [22]
En la segunda reunión, celebrada en octubre en Francia, se presentaron tres propuestas formales: ALGOL W de Niklaus Wirth junto con comentarios sobre estructuras de registros de CAR (Tony) Hoare , un lenguaje similar de Gerhard Seegmüller y un artículo de Adriaan van Wijngaarden sobre "Diseño ortogonal y descripción de un lenguaje formal". Este último, escrito en una "gramática W" casi indescifrable, resultó ser un cambio decisivo en la evolución del lenguaje. La reunión finalizó con el acuerdo de que van Wijngaarden reescribiría la propuesta de Wirth/Hoare utilizando su gramática W. [22]
Esta tarea aparentemente sencilla resultó ser más difícil de lo esperado y la reunión de seguimiento tuvo que retrasarse seis meses. Cuando se reunió en abril de 1966 en Kootwijk , el borrador de van Wijngaarden permaneció incompleto y Wirth y Hoare presentaron una versión que utilizaba descripciones más tradicionales. En general, se acordó que su artículo era "el lenguaje correcto en el formalismo equivocado". [23] A medida que se exploraron estos enfoques, se hizo evidente que había una diferencia en la forma en que se describían los parámetros que tendría efectos en el mundo real y, aunque Wirth y Hoare protestaron porque las demoras adicionales podrían volverse interminables, el comité decidió esperar la versión de van Wijngaarden. Wirth implementó entonces su definición actual como ALGOL W. [24]
En la siguiente reunión en Varsovia en octubre de 1966, [25] hubo un informe inicial del Subcomité de E/S que se había reunido en el Laboratorio Nacional de Oak Ridge y la Universidad de Illinois pero que aún no había avanzado mucho. Se volvieron a explorar las dos propuestas de la reunión anterior y esta vez surgió un nuevo debate sobre el uso de punteros ; ALGOL W los usaba solo para hacer referencia a registros, mientras que la versión de van Wijngaarden podía apuntar a cualquier objeto. Para agregar confusión, John McCarthy presentó una nueva propuesta para la sobrecarga de operadores y la capacidad de encadenar construcciones y o , y Klaus Samelson quería permitir funciones anónimas . En la confusión resultante, hubo cierta discusión sobre abandonar todo el esfuerzo. [24] La confusión continuó durante lo que se suponía que sería la reunión de ALGOL Y en Zandvoort en mayo de 1967. [22]
Finalmente, en febrero de 1968 se publicó un borrador del informe, que fue recibido con «conmoción, horror y disconformidad», [22] debido principalmente a los cientos de páginas de gramática ilegible y terminología extraña. Charles H. Lindsey intentó averiguar qué «lenguaje se escondía en él», [26] un proceso que llevó seis semanas de trabajo. El documento resultante, «ALGOL 68 con menos lágrimas», [27] tuvo una amplia difusión. En una reunión más amplia sobre procesamiento de la información celebrada en Zúrich en mayo de 1968, los asistentes se quejaron de que se les estaba imponiendo el lenguaje y de que el IFIP era «el verdadero villano de esta situación irrazonable», ya que las reuniones eran en su mayoría a puerta cerrada y no había un mecanismo formal de retroalimentación. Wirth y Peter Naur renunciaron formalmente a sus puestos de autores en el WG2.1 en ese momento. [26]
La siguiente reunión del WG2.1 tuvo lugar en Tirrenia en junio de 1968. Se suponía que iba a discutir la publicación de compiladores y otros temas, pero en su lugar se derivó en una discusión sobre el lenguaje. van Wijngaarden respondió diciendo (o amenazando) que publicaría sólo una versión más del informe. En ese momento, Naur, Hoare y Wirth habían abandonado el proyecto y varios más amenazaban con hacerlo. [28] Siguieron varias reuniones más, North Berwick en agosto de 1968, Munich en diciembre, que produjeron la publicación del Informe oficial en enero de 1969, pero también dieron como resultado la redacción de un polémico Informe de Minoría. Finalmente, en Banff, Alberta , en septiembre de 1969, el proyecto se consideró en general completo y la discusión se centró principalmente en las erratas y una Introducción al Informe muy ampliada. [29]
El esfuerzo llevó cinco años, agotó a muchos de los grandes nombres de la informática y en varias ocasiones llegó a un punto muerto por cuestiones tanto de definición como del grupo en su conjunto. Hoare publicó una "Crítica de ALGOL 68" casi inmediatamente, [30] a la que se ha hecho referencia en muchas obras. Wirth continuó desarrollando el concepto de ALGOL W y lo publicó como Pascal en 1970.
La primera implementación del estándar, basada en el borrador del Informe de finales de 1968, fue introducida por el Royal Radar Establishment en el Reino Unido como ALGOL 68-R en julio de 1970. Sin embargo, se trataba de un subconjunto del lenguaje completo, y Barry Mailloux , el editor final del Informe, bromeó diciendo que "es una cuestión de moralidad. ¡Tenemos una Biblia y tú estás pecando!" [31] Sin embargo, esta versión se volvió muy popular en las máquinas ICL y se convirtió en un lenguaje ampliamente utilizado en la codificación militar, especialmente en el Reino Unido. [32]
Entre los cambios en 68-R estaba el requisito de que todas las variables se declararan antes de su primer uso. Esto tenía una ventaja significativa, ya que permitía que el compilador fuera de una sola pasada, ya que se reservaba espacio para las variables en el registro de activación antes de usarlo. Sin embargo, este cambio también tuvo el efecto secundario de exigir que los PROC se declararan dos veces, una como declaración de los tipos y otra como cuerpo del código. Otro cambio fue eliminar el modo VOID asumido , una expresión que no devuelve ningún valor (llamada declaración en otros lenguajes) y exigir que se agregue la palabra VOID donde se hubiera asumido. Además, 68-R eliminó los comandos de procesamiento paralelo explícito basados en PAR . [31]
La primera implementación completa del lenguaje fue introducida en 1974 por CDC Netherlands para la serie de mainframes Control Data . Su uso fue limitado, principalmente en la enseñanza en Alemania y los Países Bajos. [32]
En 1976, la Universidad Carnegie Mellon introdujo una versión similar a 68-R, denominada 68S, que nuevamente era un compilador de una sola pasada basado en varias simplificaciones del original y destinado a usarse en máquinas más pequeñas como el DEC PDP-11 . También se usó principalmente con fines didácticos. [32]
No estuvo disponible una versión para mainframes de IBM hasta 1978, cuando la Universidad de Cambridge lanzó una . Estaba "casi terminada". Lindsey lanzó una versión para máquinas pequeñas, incluida la IBM PC, en 1984. [32]
Se conocen tres implementaciones de código abierto de Algol 68: [33]
"Van Wijngaarden caracterizó una vez a los cuatro autores, un tanto irónico, como: Koster: transputter, Peck: sintaxis, Mailloux: implementador, Van Wijngaarden: ideólogo del partido". – Koster.
1968: El 20 de diciembre de 1968, el Grupo de Trabajo adoptó el "Informe Final" (MR 101), que luego fue aprobado por la Asamblea General del IFIP de la UNESCO para su publicación. Se realizaron traducciones de la norma al ruso , alemán , francés y búlgaro , y más tarde al japonés y al chino . [47] La norma también se puso a disposición en Braille .
1984: El TC 97 consideró ALGOL 68 para su normalización como "Nuevo tema de trabajo" TC97/N1642 [2][3]. Alemania Occidental, Bélgica, Países Bajos, URSS y Checoslovaquia estaban dispuestos a participar en la preparación de la norma, pero la URSS y Checoslovaquia "no eran los miembros adecuados para los comités ISO adecuados"[4] y la normalización ISO de Algol 68 se estancó.[5]
1988: Posteriormente, ALGOL 68 se convirtió en uno de los estándares GOST en Rusia.
El lenguaje estándar contiene alrededor de sesenta palabras reservadas, generalmente en negrita en la letra impresa, y algunas con equivalentes de "símbolo breve":
MODO , OP , PRIO , PROC , FLEX , MONTÓN , LOC , LARGO , REF , CORTO , BITS , BOOL , BYTES , CHAR , COMPL , INT , REAL , SEMA , CADENA , VACÍO , CANAL , ARCHIVO , FORMATO , ESTRUCTURA , UNIÓN , EN "@", O r0 , ES ":=:", NO ES NO ES r0 ":/=:" ":≠:", DE "→" r0 , VERDADERO , FALSO , VACÍO , NULO "○", SALTAR "~", CO "¢", COMENTARIO "¢", PR , PRAGMAT , CASO ~ EN ~ OUSE ~ EN ~ SALIDA ~ ESAC "(~ | ~ |: ~ | ~ | ~)", PARA ~ DESDE ~ HASTA ~ POR ~ MIENTRAS ~ HACER ~ OD , SI ~ ENTONCES ~ ELIF ~ ENTONCES ~ SINO ~ FI "( ~ | ~ |: ~ | ~ | ~ )", PAR COMIENZO ~ FIN "( ~ )", IR A , GOTO , SALIR "□" r0 .
La construcción básica del lenguaje es la unidad . Una unidad puede ser una fórmula , una cláusula adjunta , un texto rutinario o una de varias construcciones técnicamente necesarias (asignación, salto, omisión, nihil). El término técnico cláusula adjunta unifica algunas de las construcciones inherentemente entre corchetes conocidas como bloque , declaración do , declaración switch en otros lenguajes contemporáneos. Cuando se utilizan palabras clave, generalmente se utiliza la secuencia de caracteres invertida de la palabra clave introductoria para terminar el encierro, por ejemplo ( IF ~ THEN ~ ELSE ~ FI , CASE ~ IN ~ OUT ~ ESAC , FOR ~ WHILE ~ DO ~ OD ). Esta sintaxis de Comando Protegido fue reutilizada por Stephen Bourne en el shell Bourne común de Unix . Una expresión también puede producir un valor múltiple , que se construye a partir de otros valores mediante una cláusula colateral . Esta construcción simplemente se parece al paquete de parámetros de una llamada a procedimiento.
Los tipos de datos básicos (llamados mode
s en la jerga de Algol 68) son real
, int
, compl
( número complejo ), bool
, char
y bits
. bytes
Por ejemplo:
INT n = 2; CO n se fija como una constante de 2. CO INT m := 3; CO m es una variable local recién creada cuyo valor se establece inicialmente en 3. CO CO Es la abreviatura de ref int m = loc int := 3; CO REAL avogadro = 6.0221415⏨23; CO Número de Avogadro CO long long real long long pi = 3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510; COMPL raíz cuadrada de menos uno = 0 ⊥ 1;
Sin embargo, la declaración REAL x;
es simplemente una sintaxis simplificada para . Es decir, es realmente el identificador constante para una referencia a una variable REAL local recién generada .REF REAL x = LOC REAL;
x
Además, en lugar de definir tanto float
y double
, como int
y long
y short
, etc., ALGOL 68 proporciona modificadores , de modo que el común actual double
se escribiría como LONG REAL o LONG LONG REAL en su lugar, por ejemplo. Las constantes de preludio max real
y min long int
se proporcionan para adaptar los programas a diferentes implementaciones.
Todas las variables deben declararse, pero la declaración no tiene por qué preceder al primer uso.
declarante primitivo: INT , REAL , COMPL , COMPLEX G , BOOL , CHAR , CADENA , BITS , BYTES , FORMATO , ARCHIVO , TUBERÍA G , CANAL , SEMA
Se pueden crear tipos complejos a partir de otros más simples utilizando varios constructores de tipos:
Para ver algunos ejemplos, consulte Comparación de ALGOL 68 y C++ .
Otros símbolos de declaración incluyen: FLEX , HEAP , LOC , REF , LONG , SHORT , EVENT S
Se puede declarar un nombre para un modo (tipo) utilizando una declaración MODE , que es similar a TYPEDEF en C/C++ y TYPE en Pascal:
INT máx=99; MODO nuevo modo = [0:9][0:máx] ESTRUCTURA ( LARGO REAL a, b, c, CORTO INT i, j, k, REF REAL r );
Esto es similar al siguiente código C:
const int max = 99 ; typedef struct { double a , b , c ; short i , j , k ; float * r ; } nuevo modo [ 9 + 1 ][ max + 1 ];
En ALGOL 68, solo aparece la indicación de modo NEWMODE a la izquierda del símbolo igual y, lo más notable, la construcción se realiza y se puede leer de izquierda a derecha sin tener en cuenta las prioridades. Además, el límite inferior de las matrices de Algol 68 es uno de manera predeterminada, pero puede ser cualquier número entero desde - max int hasta max int .
Las declaraciones de modo permiten que los tipos sean recursivos : definidos directa o indirectamente en términos de sí mismos. Esto está sujeto a algunas restricciones; por ejemplo, estas declaraciones son ilegales:
MODO A = REF A MODO A = STRUCT ( A a, B b) MODO A = PROC ( A a) A
Si bien estos son válidos:
MODO A = ESTRUCTURA ( REF A a, B b) MODO A = PROC ( REF A a) REF A
Las coerciones producen un coaccionado a partir de un coaccionado según tres criterios: el modo a priori del coaccionado antes de la aplicación de cualquier coerción, el modo a posteriori del coaccionado requerido después de esas coerciones y la posición sintáctica o "tipo" del coaccionado. Las coerciones pueden ser en cascada.
Las seis coerciones posibles se denominan desprocedimiento , desreferenciación , unión , ensanchamiento , remado y anulación . Cada coerción, excepto la unión , prescribe un efecto dinámico correspondiente sobre los valores asociados. Por lo tanto, muchas acciones primitivas pueden programarse implícitamente mediante coerciones.
Fortaleza del contexto – coerciones permitidas:
ALGOL 68 tiene una jerarquía de contextos que determinan el tipo de coerciones disponibles en un punto particular del programa. Estos contextos son:
Para obtener más detalles sobre primarios, secundarios, terciarios y cuaternarios, consulte Prioridad de operadores.
Los pragmats son directivas en el programa, típicamente sugerencias para el compilador; en lenguajes más nuevos se les llama "pragmas" (sin 't'). p. ej.
PRAGMAT montón=32 PRAGMAT PR montón=32 PR
Los comentarios se pueden insertar de varias maneras:
¢ La forma original de agregar tus 2 centavos a un programa ¢ COMENTARIO Comentario "negrita" COMENTARIO Estilo i comentario CO# Comentario de estilo ii #£ Este es un comentario en almohadilla/libra para un teclado del Reino Unido £
Normalmente, los comentarios no se pueden anidar en ALGOL 68. Esta restricción se puede eludir utilizando delimitadores de comentarios diferentes (por ejemplo, utilizar hash sólo para eliminaciones temporales de código).
ALGOL 68 es un lenguaje de programación orientado a expresiones , por lo que el valor devuelto por una sentencia de asignación es una referencia al destino. Por lo tanto, el siguiente código ALGOL 68 es válido:
REAL medio pi, un pi; un pi := 2 * ( medio pi := 2 * arc tan(1) )
Esta noción está presente en C y Perl , entre otros. Nótese que, al igual que en lenguajes anteriores como Algol 60 y FORTRAN , se permiten espacios en los identificadores, de modo que half pi
se trata de un identificador único (evitando así los problemas de guiones bajos , camel case y minúsculas).
Como otro ejemplo, para expresar la idea matemática de una suma de f(i)
i=1 a n, basta la siguiente expresión entera de ALGOL 68 :
( INT suma := 0; PARA i A n HACER suma +:= f(i) OD ; suma)
Tenga en cuenta que, al ser una expresión entera, el bloque de código anterior se puede utilizar en cualquier contexto en el que se pueda utilizar un valor entero . Un bloque de código devuelve el valor de la última expresión que evaluó; esta idea está presente en Lisp , entre otros lenguajes.
Las declaraciones compuestas terminan todas con corchetes de cierre distintivos:
Condición IF declaraciones THEN [ declaraciones ELSE ] FI forma "breve": ( condición | declaraciones | enunciados )
IF condición1 THEN declaraciones ELIF condición2 THEN declaraciones [ ELSE declaraciones ] FI formato "breve": ( condición1 | declaraciones |: condición2 | declaraciones | declaraciones )
Este esquema no solo evita el problema del else pendiente sino que también evita tener que usar BEGIN
and END
en secuencias de declaraciones integradas .
CASE switch IN declaraciones, declaraciones,... [ declaraciones OUT ] ESAC forma "breve": ( switch | declaraciones, declaraciones,... | declaraciones )
CASE switch1 IN declaraciones, declaraciones,... OUSE switch2 IN declaraciones, declaraciones,... [ declaraciones OUT ] Forma "breve" de la declaración CASE de ESAC : ( switch1 | declaraciones, declaraciones,... |: switch2 | declaraciones, declaraciones,... | declaraciones )
Ejemplo de cláusula de elección con símbolos breves :
PROC días en el mes = ( INT año, mes) INT : (mes| 31, (año÷×4=0 ∧ año÷×100≠0 ∨ año÷×400=0 | 29 | 28 ), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
Ejemplo de cláusula de elección con símbolos en negrita :
PROC días en mes = ( INT año, mes) INT : CASE mes IN 31, SI año MOD 4 EQ 0 Y año MOD 100 NE 0 O año MOD 400 EQ 0 ENTONCES 29 SI NO 28 FI , 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 Sociedad Anónima Europea ;
Ejemplo de cláusula de elección que combina símbolos en negrita y breve :
PROC días en mes = ( INT año, mes) INT : CASE mes IN31 de enero de 2018¢Feb¢ ( año MOD 4 = 0 Y año MOD 100 ≠ 0 O año MOD 400 = 0 | 29 | 28 ),¢Mar¢ 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ¢ a Dic. ¢ Sociedad Anónima Europea ;
Algol68 permitió que el conmutador fuera de tipo INT o (exclusivamente) UNION . Este último permite aplicar tipado estricto a las variables UNION . Véase union a continuación como ejemplo.
[ FOR índice ] [ FROM primero ] [ BY incremento ] [ TO último ] [ WHILE condición ] Sentencias DO OD La forma mínima de una "cláusula de bucle" es así: Sentencias DO OD
Este se consideró el bucle "universal", la sintaxis completa es:
PARA i DESDE 1 HASTA -22 -333 MIENTRAS i×i≠ 4444 HACER ~ OD
El constructo presenta varios aspectos inusuales:
INT suma sq:=0; PARA i MIENTRAS print(("Hasta ahora:",i,nueva línea)); suma sq≠70↑2HACER suma sq+:=i↑2sobredosis
Las "extensiones" posteriores del estándar Algol68 permitieron reemplazar el elemento sintáctico TO por UPTO y DOWNTO para lograr una pequeña optimización. Los mismos compiladores también incorporaron:
Puede encontrar más ejemplos en los ejemplos de código que aparecen a continuación.
ALGOL 68 admite matrices con cualquier número de dimensiones y permite la división de filas o columnas completas o parciales.
MODE VECTOR = [1:3] REAL ; # vector declaración MODE (typedef) # MODE MATRIX = [1:3,1:3] REAL ; # matriz declaración MODE (typedef) # VECTOR v1 := (1,2,3); # variable de matriz inicialmente (1,2,3) # [] REAL v2 = (4,5,6); # matriz constante, tipo equivalente a VECTOR , los límites están implícitos # OP + = ( VECTOR a,b) VECTOR : # definición de operador binario # ( VECTOR out ; FOR i FROM ⌊a TO ⌈a DO out [i] := a[i]+b[i] OD ; out); MATRIX m := (v1, v2, v1+v2); print ((m[,2:])); # una porción de la 2da y 3ra columna #
Las matrices se pueden cortar en ambos sentidos, por ejemplo:
REF VECTOR row = m[2,]; # define un REF (puntero) a la 2da fila # REF VECTOR col = m[,2]; # define un REF (puntero) a la 2da columna #
ALGOL 68 admite estructuras de campos múltiples ( STRUCT ) y modos unificados . Las variables de referencia pueden apuntar a cualquier MODO, incluidas las porciones de matriz y los campos de estructura.
Para un ejemplo de todo esto, aquí está la declaración de lista enlazada tradicional:
MODO NODO = UNIÓN ( VOID , REAL , INT , COMPL , CADENA ), LISTA = ESTRUCTURA ( NODO val, REF LISTA siguiente);
Ejemplo de uso para UNION CASE de NODE :
Las declaraciones de procedimiento ( PROC ) requieren especificaciones de tipo tanto para los parámetros como para el resultado ( VOID si no hay ninguno):
PROC máx. de real = ( REAL a, b) REAL : SI a > b ENTONCES a SI NO b FI ;
o, utilizando la forma "breve" de la declaración condicional:
PROC máx de real = ( REAL a, b) REAL : (a>b | a | b);
El valor de retorno de a proc
es el valor de la última expresión evaluada en el procedimiento. También se permiten referencias a procedimientos ( ref proc ). Los parámetros de llamada por referencia se proporcionan especificando referencias (como ref real
) en la lista de argumentos formales. El siguiente ejemplo define un procedimiento que aplica una función (especificada como parámetro) a cada elemento de una matriz:
PROC aplicar = ( REF [] REAL a, PROC ( REAL ) REAL f): PARA i DE LWB a A UPB a HACER a[i] := f(a[i]) OD
Esta simplicidad de código era inalcanzable en el predecesor de ALGOL 68, ALGOL 60 .
El programador puede definir nuevos operadores , y tanto estos como los predefinidos pueden sobrecargarse y sus prioridades pueden ser modificadas por el codificador. El siguiente ejemplo define un operador MAX
con versiones tanto diádicas como monádicas (exploración de los elementos de una matriz).
PRIO MÁXIMO = 9; OP MÁXIMO = ( INT a,b) INT : ( a>b | a | b ); OP MÁXIMO = ( REAL a,b) REAL : ( a>b | a | b ); OP MÁXIMO = ( COMPL a,b) COMPL : ( ABS a > ABS b | a | b ); OP MAX = ([] REAL a) REAL : ( REAL salida := a[ LWB a]; PARA i DESDE LWB a + 1 HASTA UPB a HACER ( a[i]>salida | salida:=a[i] ) OD ; afuera)
Técnicamente no son operadores, sino que se consideran "unidades asociadas con nombres".
Detalles específicos:
union([]int, [,]real, flex[,,,]char)
Técnicamente no son operadores, sino que se consideran "unidades asociadas con nombres".
Nota: Los cuaternarios incluyen los nombres SKIP y ~.
:=:
(alternativamente IS ) prueba si dos punteros son iguales; (alternativamente ISNT ) prueba si son desiguales.:/=:
:=:
y :/=:
son necesarios?Considere intentar comparar dos valores de puntero, como las siguientes variables, declaradas como punteros a enteros:
REF INT ip, jp
Ahora, pensemos en cómo decidir si estos dos apuntan a la misma ubicación o si uno de ellos apunta a NIL . La siguiente expresión
ip = jp
desreferenciará ambos punteros a valores de tipo INT y los comparará, ya que el operador = está definido para INT , pero no para REF INT . No es legal definir = para operandos de tipo REF INT e INT al mismo tiempo, porque entonces las llamadas se vuelven ambiguas, debido a las coerciones implícitas que se pueden aplicar: ¿deberían dejarse los operandos como REF INT y llamarse a esa versión del operador? ¿O deberían desreferenciarse aún más a INT y usar esa versión en su lugar? Por lo tanto, la siguiente expresión nunca puede hacerse legal:
ip = NIL
De ahí la necesidad de construcciones separadas que no estén sujetas a las reglas normales de coerción de operandos a operadores. Pero hay un problema. Las siguientes expresiones:
ip :=: jp
ip :=: NIL
Si bien son legales, probablemente no harán lo que se podría esperar. Siempre devolverán FALSO , porque están comparando las direcciones reales de las variables y , en lugar de lo que apuntan . Para lograr el efecto correcto, uno tendría que escribirip
jp
ip :=: REF INT(jp)
ip :=: REF INT(NIL)
La mayoría de los caracteres "especiales" de Algol (⊂, ≡, ␣, ×, ÷, ≤, ≥, ≠, ¬, ⊃, ≡, ∨, ∧, →, ↓, ↑, ⌊, ⌈, ⎩, ⎧, ⊥, ⏨, ¢, ○ y □) se pueden encontrar en el teclado IBM 2741 con el cabezal de impresión "pelota de golf" APL insertado; estos se volvieron disponibles a mediados de la década de 1960 mientras se redactaba ALGOL 68. Estos caracteres también son parte del estándar Unicode y la mayoría de ellos están disponibles en varias fuentes populares .
Transput es el término utilizado para referirse a las funciones de entrada y salida de ALGOL 68. Incluye procedimientos predefinidos para la transput sin formato, con formato y binaria. Los archivos y otros dispositivos de transput se manejan de manera consistente e independiente de la máquina. El siguiente ejemplo imprime una salida sin formato en el dispositivo de salida estándar :
imprimir ((nueva página, "Título", nueva línea, "El valor de i es ", i, "y x[i] es ", x[i], nueva línea))
Tenga en cuenta los procedimientos predefinidos newpage
y newline
pasados como argumentos.
El TRANSPORTE se considera de LIBROS , CANALES y ARCHIVOS :
match
.establish, create, open, associate, lock, close, scratch
.char number, line number, page number
.space
, backspace
, newline
, newpage
.get good line, get good page, get good book
, yPROC set=(REF FILE f, INT page,line,char)VOID:
on logical file end, on physical file end, on page end, on line end, on format end, on value error, on char error
:"Transput formateado" en el transput de ALGOL 68 tiene su propia sintaxis y patrones (funciones), con FORMAT incrustados entre dos caracteres $. [50]
Ejemplos:
printf (($2l"La suma es:"x, g(0)$, m + n)); ¢ imprime lo mismo que: ¢ imprimir ((nueva línea, nueva línea, "La suma es:", espacio, entero (m + n, 0))
ALGOL 68 admite la programación de procesamiento paralelo. Mediante la palabra clave PAR , una cláusula colateral se convierte en una cláusula paralela , donde la sincronización de acciones se controla mediante semáforos . En A68G, las acciones paralelas se asignan a subprocesos cuando están disponibles en el sistema operativo anfitrión . En A68S se implementó un paradigma diferente de procesamiento paralelo (ver a continuación).
PROC eat = VOID : ( muffins-:=1; print(("¡Mmm!",nueva línea))), hablar = VOID : ( palabras-:=1; imprimir(("Yak...",nueva línea))); INT muffins := 4, palabras := 8; SEMA boca = NIVEL 1; PAR COMIENZA MIENTRAS muffins > 0 HACER ABAJO boca; comer; ARRIBA boca OD , MIENTRAS palabras > 0 HACER ABAJO boca; hablar; Boca ARRIBA EXTREMO OD
Por sus complejidades técnicas, ALGOL 68 necesita una cornucopia de métodos para negar la existencia de algo:
SKIP , "~" o "?" C – un valor indefinido siempre sintácticamente válido, EMPTY – el único valor admisible para VOID , necesario para seleccionar VOID en una UNION , VOID – sintácticamente como un MODE , pero no uno, NIL o "○" – un nombre que no denota nada, de un modo de referencia no especificado,() o específicamente [1:0] INT : un vacío es una matriz vacía (aquí específicamente de MODE [] INT ). undefined : un procedimiento de informes estándar que genera una excepción en el sistema de tiempo de ejecución.ℵ – Se utiliza en el informe de normas para inhibir la introspección de ciertos tipos, por ejemplo, SEMA
El término NIL IS var siempre se evalúa como VERDADERO para cualquier variable (pero vea más arriba el uso correcto de IS :/=:), mientras que no se sabe a qué valor se evalúa una comparación x < SKIP para cualquier entero x .
ALGOL 68 deja intencionalmente sin definir lo que sucede en caso de desbordamiento de entero , la representación del bit entero y el grado de precisión numérica para el punto flotante.
Ambos informes oficiales incluían algunas características avanzadas que no formaban parte del lenguaje estándar. Estas se indicaban con una ℵ y se consideraban efectivamente privadas. Algunos ejemplos incluyen "≮" y "≯" para plantillas, OUTTYPE / INTYPE para tipado rudimentario y los operadores STRAIGHTOUT y STRAIGHTIN para "enderezar" estructuras y matrices anidadas.
Este programa de ejemplo implementa la Criba de Eratóstenes para encontrar todos los números primos menores que 100. NIL es el análogo de ALGOL 68 del puntero nulo en otros lenguajes. La notación x OF y accede a un miembro x de un STRUCT y .
COMIENZO # Tamiz de números primos Algol-68, estilo funcional # Error de PROC = ( CADENA s) VACÍO : (print((nueva línea, "error:", s, nueva línea)); GOTO stop); PROC uno a = ( INT n) LISTA : ( PROC f = ( INT m,n) LISTA : (m>n | NIL | cons(m, f(m+1,n))); f(1,n)); LISTA DE MODOS = NODO REF ; NODO DE MODOS = ESTRUCTURA ( INT h, LISTA t); PROC cons = ( INT n , LISTA l) LISTA : NODO HEAP := (n,l); PROC hd = ( LISTA l) INT : ( l ES NULO | error("hd NIL "); SALTAR | h DE l ); PROC tl = ( LISTA l) LISTA : ( l ES NULO | error("tl NIL "); SALTAR | t DE l ); PROC mostrar = ( LISTA l) VOID : ( l NO ES NULO | print((" ",whole(hd(l),0))); mostrar(tl(l))); PROC filtro = ( PROC ( INT ) BOOL p, LISTA l) LISTA : SI l ES NULO ENTONCES NULO ELIF p(hd(l)) ENTONCES cons(hd(l), filtro(p,tl(l))) DE LO CONTRARIO filtro(p, tl(l)) FI ; PROC tamiz = ( LISTA l) LISTA : SI l ES NULO ENTONCES NULO DE LO CONTRARIO PROC no múltiple = ( INT n) BOOL : n MOD hd(l) ~= 0; cons(hd(l), sieve( filter( no múltiple, tl(l) ))) ES ; PROC primos = ( INT n) LISTA : tamiz( tl( uno a(n) )); mostrar( primos(100) )FIN
Nota: Las computadoras de la era soviética Elbrus-1 (Elbrus-1) y Elbrus-2 se crearon utilizando el lenguaje de alto nivel Elbrus-76 (AL-76), en lugar del lenguaje ensamblador tradicional. El Elbrus-76 se parece al Algol-68, la principal diferencia son los tipos de enlace dinámicos en Elbrus-76 admitidos a nivel de hardware. El Elbrus-76 se utiliza para aplicaciones, control de trabajos y programación del sistema. [54]
Tanto ALGOL 68C como ALGOL 68-R están escritos en ALGOL 68, lo que convierte a ALGOL 68 en una aplicación en sí misma. Otras aplicaciones incluyen:
Una característica de ALGOL 68, heredada de la tradición ALGOL , son sus diferentes representaciones. Hay un lenguaje de representación utilizado para describir algoritmos en trabajos impresos, un lenguaje estricto (definido rigurosamente en el Informe) y un lenguaje de referencia oficial destinado a ser utilizado en la entrada del compilador. Los ejemplos contienen palabras en NEGRITA , este es el lenguaje ESTRICTO . Las palabras reservadas de ALGOL 68 están efectivamente en un espacio de nombres diferente al de los identificadores, y se permiten espacios en los identificadores, por lo que el siguiente fragmento es legal:
INT un int real = 3;
El programador que escribe código ejecutable no siempre tiene la opción de usar la tipografía BOLD o subrayar el código, ya que esto puede depender del hardware y de cuestiones culturales. Se han ideado diferentes métodos para indicar estos identificadores. Esto se denomina régimen de stropping . Por ejemplo, todas o algunas de las siguientes pueden ser representaciones de programación disponibles :
INT un int real = 3; # el lenguaje ESTRICTO #'INT'A REAL INT = 3; # estilo de alineación de QUOTE #.INT UN INT REAL = 3; # estilo de alineación de PUNTO # INT un int real = 3; # estilo de alineación SUPERIOR # int a_real_int = 3; # Estilo de corrección de RES, hay 61 palabras reservadas aceptadas #
Todas las implementaciones deben reconocer al menos POINT, UPPER y RES dentro de las secciones PRAGMAT. De estos, el uso de POINT y UPPER es bastante común, mientras que el uso de RES es una contradicción con la especificación (ya que no hay palabras reservadas). QUOTE (entrecomillado con apóstrofo simple) fue la recomendación original, mientras que el uso de entrecomillado con apóstrofo coincidente, común en ALGOL 60, no se usa mucho en ALGOL 68. [57]
Los siguientes caracteres fueron recomendados para portabilidad y denominados "caracteres valiosos" en el Informe sobre la representación de hardware estándar de Algol 68 Archivado el 2 de enero de 2014 en Wayback Machine :
Esto reflejaba un problema en la década de 1960, cuando algunos equipos no soportaban minúsculas ni otros caracteres no ASCII ; de hecho, en el informe de 1973 se escribió: "Cuatro caracteres valiosos —"|", "_", "[" y "]" — a menudo se codifican de forma diferente, incluso en instalaciones que nominalmente usan el mismo conjunto de caracteres".
ALGOL 68 permite que cada lenguaje natural defina su propio conjunto de palabras clave Algol-68. Como resultado, los programadores pueden escribir programas utilizando palabras clave de su idioma nativo. A continuación se muestra un ejemplo de un procedimiento simple que calcula "el día siguiente", el código está en dos idiomas: inglés y alemán. [ cita requerida ]
# Fecha del día siguiente - Variante en inglés # MODE DATE = STRUCT ( INT día, STRING mes, INT año); PROC el día siguiente = ( DATE x) DATE : IF día OF x < longitud del mes (mes OF x, año OF x) THEN (día OF x + 1, mes OF x, año OF x) ELIF mes OF x = "diciembre" THEN (1, "enero", año OF x + 1) ELSE (1, sucesor del mes (mes OF x), año OF x) FI ;
# Nachfolgetag - Deutsche Variante # MENGE DATUM = TUPEL ( etiqueta GANZ , WORT monat, GANZ jahr); FUNKTION naechster tag nach = ( DATUM x) DATUM : WENN tag VON x < monatslaenge(monat VON x, jahr VON x) DANN (tag VON x + 1, monat VON x, jahr VON x) WENNABER monat VON x = "diciembre" DANN (1, "enero", jahr VON x + 1) ANSONSTEN (1, nachfolgemonat(monat VON x), jahr VON x) ENDEWENN ;
Ejemplo ruso/soviético: en inglés, la declaración de caso de Algol68 se lee CASE ~ IN ~ OUT ~ ESAC , en cirílico se lee выб ~ в ~ либо ~ быв .
Salvo que se indique lo contrario (con un superíndice ), el lenguaje descrito anteriormente es el del "Informe Revisado (r1) ".
El lenguaje original (según el "Informe final" r0 ) difiere en la sintaxis del modo cast y tenía la característica de proceduring , es decir, forzar el valor de un término a un procedimiento que evalúa el término. Proceduring estaría destinado a hacer que las evaluaciones sean perezosas . La aplicación más útil podría haber sido la evaluación en cortocircuito de operadores booleanos. En:
OP ANDF = ( BOOL a, PROC BOOL b) BOOL :(a | b | FALSO ); OP ORF = ( BOOL a, PROC BOOL b) BOOL :(a | VERDADERO | b);
b sólo se evalúa si a es verdadero.
Como se define en ALGOL 68, no funcionó como se esperaba, por ejemplo en el código:
SI FALSO ANDF CO proc bool: CO ( print ("No debe ejecutarse"); VERDADERO ) ENTONCES ...
En contra de las expectativas ingenuas de los programadores, se ejecutaría la impresión , ya que solo se procesó el valor de la cláusula incluida elaborada después de ANDF . La inserción textual del PROC BOOL comentado : hace que funcione.
Algunas implementaciones emulan el comportamiento esperado para este caso especial por extensión del lenguaje.
Antes de la revisión, el programador podría decidir que los argumentos de un procedimiento se evalúen en serie en lugar de colateralmente utilizando punto y coma en lugar de comas ( gommas ).
Por ejemplo en:
Prueba PROC = ( REAL a; REAL b) :......prueba (x MÁS 1, x);
Se garantiza que el primer argumento a probar se evaluará antes que el segundo, pero de la manera habitual:
Prueba PROC = ( REAL a, b) :......prueba (x MÁS 1, x);
entonces el compilador podría evaluar los argumentos en el orden que quisiera.
Tras la revisión del informe, se han propuesto algunas ampliaciones del lenguaje para ampliar su aplicabilidad:
ENVIRON
y de ALGOL 68C [59]USING
Hasta ahora, solo se ha implementado una parametrización parcial en Algol 68 Genie.
El lenguaje S3 que se utilizó para escribir el sistema operativo ICL VME y mucho otro software del sistema en la Serie ICL 2900 fue un derivado directo de Algol 68. Sin embargo, omitió muchas de las características más complejas y reemplazó los modos básicos con un conjunto de tipos de datos que se asignaban directamente a la arquitectura de hardware de la Serie 2900.
ALGOL 68R de RRE fue la primera implementación de subconjunto de ALGOL 68, que se ejecutó en el ICL 1900. Basado en el lenguaje original, las principales restricciones del subconjunto fueron la definición antes del uso y la ausencia de procesamiento en paralelo. Este compilador fue popular en las universidades del Reino Unido en la década de 1970, donde muchos estudiantes de informática aprendieron ALGOL 68 como su primer lenguaje de programación; el compilador era famoso por sus buenos mensajes de error.
ALGOL 68RS (RS) de RSRE era un sistema de compilación portátil escrito en ALGOL 68RS (arrancado a partir de ALGOL 68R) e implementado en una variedad de sistemas, incluidos ICL 2900 / Serie 39 , Multics y DEC VAX/VMS . El lenguaje se basaba en el Informe revisado, pero con restricciones de subconjunto similares a las de ALGOL 68R. Este compilador sobrevive en forma de un compilador de Algol68 a C.
En ALGOL 68S (S) de la Universidad Carnegie Mellon, se mejoró la potencia del procesamiento paralelo añadiendo una extensión ortogonal, eventing . Toda declaración de variable que contuviera la palabra clave EVENT hacía que las asignaciones a esta variable fueran elegibles para la evaluación paralela, es decir, el lado derecho se convertía en un procedimiento que se trasladaba a uno de los procesadores del sistema multiprocesador C.mmp . Los accesos a dichas variables se retrasaban después de la finalización de la asignación.
Cambridge ALGOL 68C (C) fue un compilador portátil que implementó un subconjunto de ALGOL 68, restringiendo las definiciones de operadores y omitiendo la recolección de basura, las filas flexibles y el transporte formateado.
Algol 68 Genie (G) de M. van der Veer es una implementación de ALGOL 68 para las computadoras y sistemas operativos actuales.
"A pesar de las buenas intenciones, un programador puede violar la portabilidad al emplear inadvertidamente una extensión local. Para protegerse contra esto, cada implementación debe proporcionar una opción pragmática PORTCHECK. Mientras esta opción esté vigente, el compilador imprime un mensaje para cada construcción que reconoce como violadora de alguna restricción de portabilidad". [67]
{{cite book}}
: |journal=
ignorado ( ayuda ){{cite web}}
: CS1 maint: copia archivada como título ( enlace ){{cite web}}
: CS1 maint: copia archivada como título ( enlace )