POP-2 (también llamado POP2 ) es un lenguaje de programación desarrollado alrededor de 1970 a partir del lenguaje anterior POP-1 (desarrollado por Robin Popplestone en 1968, originalmente llamado COWSEL ) por Robin Popplestone y Rod Burstall en la Universidad de Edimburgo . Sacó raíces de muchas fuentes: los lenguajes Lisp y ALGOL 60 , e ideas teóricas de Peter J. Landin . Utilizaba un compilador incremental , lo que le daba algo de la flexibilidad de un lenguaje interpretado , incluyendo permitir nuevas definiciones de funciones en tiempo de ejecución y modificación de definiciones de funciones mientras se ejecuta un programa (ambas características de la compilación dinámica ), sin la sobrecarga de un lenguaje interpretado. [1]
La sintaxis de POP-2 es similar a ALGOL , excepto que las asignaciones están en orden inverso: en lugar de escribir
un := 3;
uno escribe
3 -> un;
La razón de esto es que el lenguaje tiene una noción explícita de pila de operandos . Por tanto, la asignación anterior se puede escribir como dos declaraciones separadas :
3;
que evalúa el valor 3 y lo deja en la pila, y
-> un;
que saca el valor superior de la pila y lo asigna a la variable 'a'. De manera similar, la llamada a la función
f(x, y, z);
Se puede escribir como
x, y, z; F();
(las comas y el punto y coma son en gran medida intercambiables) o incluso
x, y, zf;
o
(x, y, z).f;
Debido al paradigma basado en pilas , no es necesario distinguir entre declaraciones y expresiones ; por lo tanto, las dos construcciones
si a > b entonces c -> mi demás re -> mi cerca;
y
si a > b entonces C demás d cerrar -> e;
son equivalentes (uso de close
, ya que aún endif
no se había convertido en una notación común end-of-if-clause
).
No existen construcciones de lenguaje especiales para crear matrices o estructuras de registros como se entienden comúnmente: en cambio, se crean con la ayuda de funciones integradas especiales, por ejemplo, newarray
[2] (para matrices que pueden contener cualquier tipo de elemento) y newanyarray
[3 ] para crear tipos restringidos de elementos.
Por lo tanto, los descriptores de acceso al elemento de matriz y al campo de registro son simplemente casos especiales de una función doblete : esta es una función que tenía otra función adjunta como su actualizador , [4] que se llama en el lado receptor de una asignación. Por lo tanto, si la variable a
contiene una matriz, entonces
3 -> un(4);
es equivalente a
actualizador(a)(3, 4);
la función incorporada updater
que devuelve el actualizador del doblete. Por supuesto, updater
es un doblete y se puede utilizar para cambiar el componente actualizador de un doblete.
Las variables pueden contener valores de cualquier tipo, incluidas funciones, que son objetos de primera clase. Así, las siguientes construcciones
función máxima xy; si x > y entonces x; de lo contrario, cerrará el final;
y
vars máx; lambda xy; si x > y entonces x si no y cerrar final -> max;
son equivalentes.
Una operación interesante sobre funciones es la aplicación parcial (a veces denominada curry ). En una aplicación parcial, algunos de los argumentos más a la derecha de la función (que son los últimos colocados en la pila antes de que la función participe) se congelan en valores dados, para producir una nueva función de menos argumentos, que es un cierre de la función. función original. Por ejemplo, considere una función para calcular polinomios generales de segundo grado:
función poli2 xabc; a * x * x + b * x + c final;
Esto puede vincularse, por ejemplo, como
vars menos1cuadrado; poli2(% 1, -2, 1%) -> menos1cuadrado;
tal que la expresión
menos1 al cuadrado(3)
aplica el cierre de poli2 con tres argumentos congelados, al argumento 3, devolviendo el cuadrado de (3 - 1), que es 4. La aplicación de la función parcialmente aplicada provoca que los valores congelados (en este caso 1, -2, 1 ) para agregarlo a lo que ya esté en la pila (en este caso 3), después de lo cual se invoca la función original poli2. Luego utiliza los cuatro elementos superiores de la pila, produciendo el mismo resultado que
poli2(3, 1, -2, 1)
es decir
1*3*3 + (-2)*3 + 1
En POP-2 fue posible definir nuevas operaciones (operadores en términos modernos). [5]
operación vars 3 +*; lambda xy; x * x + y * y final -> nonop +*
La primera línea declara una nueva operación +* con precedencia (prioridad) 3. La segunda línea crea una función f(x,y)=x*x+y*y y la asigna a la operación recién declarada +*.
La versión original de POP-2 se implementó en una computadora Elliott 4130 en la Universidad de Edimburgo (con sólo 64 KB de RAM, duplicada a 128 KB en 1972). [6]
POP-2 fue trasladado a la serie ICT 1900 en un 1909 en la Universidad de Lancaster por John Scott en 1968.
A mediados de la década de 1970, POP-2 fue portado a BESM-6 (Sistema POPLAN).
En 1978, Hamish Dewar implementó una versión de POP-2 específicamente para uso de estudiantes universitarios de la Universidad de Edimburgo en la clase AI2 (Inteligencia Artificial, nivel de segundo año) utilizando el sistema operativo EMAS . Esta implementación fue escrita desde cero en el lenguaje de programación de Edimburgo, IMP . [7]
Se implementaron versiones posteriores para Computer Technology Limited (CTL) Modular One, PDP-10 , serie ICL 1900 (que ejecuta el sistema operativo George ). Julian Davies, en Edimburgo, implementó una versión extendida de POP-2, a la que llamó POP-10 en la computadora PDP-10 que ejecutaba TOPS-10 . Este fue el primer dialecto de POP-2 que trató las mayúsculas y minúsculas como significativas en los nombres de los identificadores, usó minúsculas para la mayoría de los identificadores del sistema y admitió identificadores largos con más de 8 caracteres.
Poco después, Robert Rae y Allan Ramsay implementaron en Edimburgo una nueva implementación conocida como WPOP (para WonderPop), en un proyecto financiado por un consejo de investigación. Esa versión introdujo espacios de direcciones enjaulados, algo de escritura sintáctica en tiempo de compilación (por ejemplo, para números enteros y reales) y algunas construcciones de coincidencia de patrones para usar con una variedad de estructuras de datos .
Paralelamente, Steve Hardy de la Universidad de Sussex implementó un subconjunto de POP-2, al que llamó POP-11 , que se ejecutaba en una computadora PDP-11/40 de Digital Equipment Corporation (DEC). Originalmente fue diseñado para ejecutarse en el sistema operativo DEC RSX-11D, en modo de tiempo compartido para enseñanza, pero eso causó tantos problemas que se instaló y utilizó una versión anterior de Unix . Esa versión de Pop-11 se escribió en lenguaje ensamblador Unix y el código se compiló incrementalmente en un código de bytes intermedio que se interpretó. Ese puerto se completó alrededor de 1976 y, como resultado, el Pop-11 se utilizó en varios lugares para la enseñanza. Para respaldar su función de enseñanza, se modificaron muchas de las características sintácticas de POP-2, por ejemplo, reemplazando function ... end
y define ... enddefine
agregando una variedad más amplia de construcciones de bucles con corchetes de cierre para que coincidan con sus corchetes de apertura en lugar del uso de close
para todos los bucles en POP-2. . Pop-11 también introdujo un comparador de patrones para estructuras de listas, lo que facilita mucho la enseñanza de la programación de inteligencia artificial (IA).
Alrededor de 1980, Steve Hardy y John Gibson trasladaron Pop-11 a una computadora VAX-11/780 , y poco después fue reemplazado por un compilador incremental completo (que produce código de máquina en lugar de un código intermedio interpretado). La existencia del compilador y todas sus subrutinas en tiempo de ejecución hizo posible soportar extensiones de lenguaje mucho más ricas que las posibles con las macros y, como resultado, Steve Hardy, Chris Mellish y John Gibson utilizaron Pop-11 para producir un implementación de Prolog , utilizando la sintaxis estándar de Prolog, y el sistema combinado pasó a ser conocido como Poplog , al que más tarde se agregaron Common Lisp y Standard ML . Posteriormente, esta versión se transfirió a una variedad de máquinas y sistemas operativos y, como resultado, Pop-11 se convirtió en el dialecto dominante de POP-2, todavía disponible en el sistema Poplog.
Alrededor de 1986, una nueva empresa de inteligencia artificial, Cognitive Applications Ltd., colaboró con miembros de la Universidad de Sussex para producir una variante de Pop-11 llamada AlphaPop que se ejecuta en computadoras Apple Mac , con gráficos integrados. Esto se utilizó para muchos proyectos comerciales y para enseñar programación de IA en varias universidades. El hecho de que se implementara en uno de los primeros dialectos de C, utilizando un compilador idiosincrásico, hizo que fuera muy difícil mantener y actualizar a nuevas versiones del sistema operativo Mac. Además, AlphaPop no era " limpio de 32 bits " debido al uso de bits de dirección altos como bits de etiqueta para indicar el tipo de objetos, lo que era incompatible con el uso de memoria superior a 8 Mb en Macintosh posteriores.