En los lenguajes de programación Lisp , un fexpr es una función cuyos operandos se le pasan sin ser evaluados. Cuando se llama un fexpr, solo se evalúa el cuerpo del fexpr; no se llevan a cabo otras evaluaciones excepto cuando sean iniciadas explícitamente por la fexpr. Por el contrario, cuando se llama a una función Lisp ordinaria, los operandos se evalúan automáticamente y solo se proporcionan a la función los resultados de estas evaluaciones; y cuando se llama a una macro Lisp (tradicional) , los operandos se pasan sin evaluar, pero cualquier resultado que devuelva la función macro se evalúa automáticamente.
Origen del nombre "fexpr"
En Lisp temprano, el entorno asignaba cada símbolo a una lista de asociación , en lugar de directamente a un valor. [1] Las claves estándar para estas listas incluían dos claves que se usaban para almacenar un valor de datos, que se buscarían cuando el símbolo apareciera como argumento ( APVAL y APVAL1 ); y cuatro teclas utilizadas para almacenar una función, que se buscarán cuando aparezca el símbolo como operador. De las teclas de función, SUBR indicó una función ordinaria compilada, cuyos operandos se evaluaron y se le pasaron; FSUBR indicó una forma especial compilada, cuyos operandos se pasaron sin evaluar; EXPR indicó una función ordinaria definida por el usuario; y FEXPR indicó una forma especial definida por el usuario. La única diferencia entre un FEXPR y un EXPR era si los operandos se evaluaban automáticamente.
En el uso original estricto, un FEXPR es por lo tanto una función definida por el usuario cuyos operandos se pasan sin evaluar. Sin embargo, en un uso posterior, el término fexpr puede describir cualquier función de primera clase cuyos operandos se pasen sin evaluar, independientemente de si la función es primitiva o definida por el usuario. [2]
Clave | Historias | Definido por | Función / forma especial |
---|---|---|---|
APVAL | valor de los datos | - | - |
APVAL1 | valor de los datos | - | - |
SUBR | función | sistema | función |
FSUBR | función | sistema | forma especial |
EXPR | función | usuario | función |
FEXPR | función | usuario | forma especial |
Ejemplo
Como una simple ilustración de cómo funcionan los fexprs, aquí hay una definición de fexpr escrita en el lenguaje de programación Kernel , que es similar a Scheme . (Por convención en Kernel, los nombres de fexprs siempre comienzan con $ .)
( $ define! $ f ( $ vau ( x y z ) e ( $ if ( > =? ( eval x e ) 0 ) ( eval y e ) ( eval z e ))))
Esta definición proporciona un fexpr llamado $ f , que toma tres operandos. Cuando se llama al fexpr, se crea un entorno local ampliando el entorno estático donde se definió el fexpr. A continuación, se crean enlaces locales: símbolos x , y , y z están vinculados a los tres operandos de la llamada al fexpr, y el símbolo e está vinculado al entorno dinámico desde el que se llama al fexpr. El cuerpo del fexpr, ($ si ... ) , luego se evalúa en este entorno local, y el resultado de esa evaluación se convierte en el resultado de la llamada al fexpr. El efecto neto es que el primer operando se evalúa en el entorno dinámico y, dependiendo de si el resultado de esa evaluación no es negativo, se evalúa el segundo o el tercer operando y se devuelve ese resultado. El otro operando, ya sea el tercero o el segundo, no se evalúa.
Este ejemplo tiene un alcance estático : el entorno local es una extensión del entorno estático. Antes de 1980, los lenguajes Lisp que admitían fexprs tenían un ámbito principalmente dinámico: el entorno local era una extensión del entorno dinámico, en lugar del entorno estático. [3] Sin embargo, a veces era necesario proporcionar un nombre local para el entorno dinámico, para evitar capturar los nombres de los parámetros locales. [4]
Uso generalizado y desaprobación
El soporte de Fexpr continuó en Lisp 1.5 , el último dialecto sustancialmente estándar de Lisp antes de que se fragmentara en varios idiomas. [5] En la década de 1970, los dos lenguajes Lisp dominantes [6] - MacLisp e Interlisp - ambos admitían fexprs. [7]
En la Conferencia de 1980 sobre Lisp y Programación Funcional , Kent Pitman presentó un artículo "Formas especiales en Lisp" en el que discutió las ventajas y desventajas de las macros y fexprs, y finalmente condenó las fexprs. Su objeción central fue que, en un dialecto Lisp que permite fexprs, el análisis estático no puede determinar en general si un operador representa una función ordinaria o un fexpr; por lo tanto, el análisis estático no puede determinar si los operandos serán evaluados o no. En particular, el compilador no puede decir si una subexpresión se puede optimizar de forma segura, ya que la subexpresión podría tratarse como datos no evaluados en tiempo de ejecución.
Los MACRO ofrecen un mecanismo adecuado para especificar definiciones de formas especiales y ... Los de FEXPR no lo hacen. ... Se sugiere que, en el diseño de futuros dialectos Lisp, se debería considerar seriamente la proposición de que Los FEXPR deben omitirse del idioma por completo. [8]
Desde el declive de MacLisp e Interlisp, los dos lenguajes Lisp que habían alcanzado el dominio en 1993 [9] - Scheme y Common Lisp - no admiten fexprs. newLISP admite fexprs, pero los llama "macros". En Picolisp, todas las funciones integradas son fsubrs, mientras que las funciones de nivel Lisp son exprs, fexprs, lexprs o una mezcla de ellas.
fexprs desde 1980
Comenzando con el 3-Lisp de Brian Smith en 1982, se han ideado varios dialectos Lisp experimentales para explorar los límites de la reflexión computacional . Para respaldar la reflexión, estos Lisps admiten procedimientos que pueden cosificar varias estructuras de datos relacionadas con la llamada a ellos, incluidos los operandos no evaluados de la llamada, lo que hace que estos procedimientos sean fexprs. A finales de la década de 1990, los fexprs se habían asociado principalmente con la reflexión computacional. [10]
Se han obtenido algunos resultados teóricos sobre fexprs. En 1993, John C. Mitchell usó Lisp con fexprs como un ejemplo de un lenguaje de programación cuyas expresiones fuente no pueden ser formalmente abstractas (porque la sintaxis concreta de una expresión fuente siempre puede ser extraída por un contexto en el que es un operando de fexpr ). [11] En 1998, Mitchell Wand demostró que agregar un dispositivo fexpr al cálculo lambda , un dispositivo que suprime la reescritura de operandos, produce un sistema formal con una teoría de ecuaciones trivial , lo que hace imposible realizar optimizaciones de fuente a fuente sin un conjunto -análisis del programa . [10] En 2007, John N. Shutt propuso una extensión del cálculo lambda que modelaría fexprs sin suprimir la reescritura de operandos, evitando aparentemente el resultado de Wand. [12]
Ver también
Los siguientes lenguajes implementan fexprs o casi equivalentes:
- Lenguaje de programación ECL
- Io (lenguaje de programación)
- Kernel (lenguaje de programación)
- newLISP
- Picolisp
- R (lenguaje de programación)
- REBOL
Notas al pie
- ^ McCarthy et al., Lisp I Programmer's Manual , págs. 88-91.
- ↑ Pitman, The Revised MacLisp Manual , p. 75.
- ^ Steele y Gabriel, "La evolución de Lisp", págs. 239-240.
- ↑ Pitman, The Revised MacLisp Manual , p. 62
- ^ Steele y Gabriel, "La evolución de Lisp", págs. 231-232.
- ^ Steele y Gabriel, "La evolución de Lisp", p. 235.
- ↑ Pitman, The Revised MacLisp Manual , p. 182.
- ^ Pitman, "Formas especiales en Lisp", p. 179.
- ^ Steele y Gabriel, "La evolución de Lisp", págs. 245–248
- ↑ a b Wand, "La teoría de Fexprs es trivial", p. 189.
- ^ Mitchell, "Sobre la abstracción y el poder expresivo de los lenguajes de programación", sección 7.
- ^ Shutt, "vau-calculi y la teoría de fexprs".
Referencias
- McCarthy, J .; Brayton, R .; Edwards, D .; Fox, P .; Hodes, L .; Luckham, D .; Maling, K .; Park, D .; Russell, S. (marzo de 1960), LISP I Programmers Manual (PDF) , Boston , Massachusetts : Grupo de Inteligencia Artificial, Centro de Computación y Laboratorio de Investigación del MIT Consultado el 11 de mayo de 2010.
- John C. Mitchell, "Sobre la abstracción y el poder expresivo de los lenguajes de programación" , Science of Computer Programming 212 (1993), págs. 141-163. (Número especial de artículos de Symp. Theor. Aspects of Computer Software, Sendai, Japón, 1991.) Consultado el 24 de enero de 2008.
- Kent M. Pitman, "Formas especiales en Lisp" , Actas de la Conferencia ACM de 1980 sobre Lisp y programación funcional, 1980, págs. 179-187. Consultado el 25 de enero de 2008.
- Kent M. Pitman, The Revised MacLisp Manual (edición del sábado por la noche), MIT Laboratory for Computer Science Technical Report 295, 21 de mayo de 1983.
- John N. Shutt, "vau-calculi and the theory of fexprs", charla, New England Programming Languages and Systems Symposium Series (NEPLS) , 18 de octubre de 2007. Resumen consultado el 27 de enero de 2008.
- Guy L. Steele y Richard P. Gabriel, "La evolución de Lisp", ACM SIGPLAN Notices 28 no. 3 (marzo de 1993), págs. 231–270.
- Mitchell Wand, "La Teoría de Fexprs es Trivial" , Lisp y Computación Simbólica 10 no. 3 (mayo de 1998), págs. 189–199. Consultado el 25 de enero de 2008.