haskell programming-languages metaprogramming quoting nemerle

haskell - ¿Cuál es el significado de "cuasi" en cuasiquotaciones?



programming-languages metaprogramming (5)

Algunos lenguajes como Haskell (o Nemerle) tienen quasiquotations . Me pregunto qué significa "cuasi" y si también existen "citas" sin la parte "cuasi".


Básicamente, básicamente significa que puede poner un signo de dólar dentro de la oferta y volver a cambiar al código que no está entre comillas:

<[ WriteLine( $(ReadLine()) ) ]>

Esto producirá en tiempo de ejecución una cadena ingresada en tiempo de compilación (de hecho, no creo que esto funcione, por ejemplo, en Visual Studio, ya que ReadLine requiere entrada de consola, pero puede leer desde archivos, red, etc.).


Creo que esta noción proviene de los lenguajes Lisp.

El programa escrito en Lisp consiste en series de listas de listas de listas, etc., como esta:

(defn f [x y] (+ x y))

Debido a tal uniformidad, es posible representar y manipular dicho código como datos, por lo que la secuencia de caracteres anterior se interpreta como una lista literal. Esta es una característica muy útil de Lisps, una de sus características distintivas. Para mayor comodidad, los lenguajes Lisp permiten ''citar'' secuencias significativas, convirtiéndolas de definiciones y expresiones en listas. Se parece a esto:

''(defn f [x y] (+ x y))

En este caso, es una lista literal, directamente disponible para la desestructuración usando análogos de la head y la tail de Haskell y otros métodos. Entonces, ''cita'' significa ''hacer un valor literal de la lista''.

Sin embargo, no es conveniente manipular listas directamente con funciones de head y tail . Se vuelve notable cuando comienzas a escribir macros complejas o incluso macro generadores de macros. Así que aquí viene ''cuasiquotación'', literalmente ''casi una cita''. Por lo general, la cuasiquotación parece una cita simple (pero con otro símbolo de comillas):

`(defn f [x y] (+ x y))

Pero es una cosa mucho más poderosa. En la lista resumida, puede reemplazar elementos arbitrarios con sus valores reales del ámbito externo, obteniendo esencialmente algo así como patrones. Ejemplo:

(let [z 10] `(defn f [x y] (+ x y ~z)))

Aquí estamos vinculando el valor de 10 a la variable z y luego lo estamos sustituyendo dentro de quasiquote. Esta expresión produce

''(defn f [x y] (+ x y 10))

Este es un simple ejemplo; Los lenguajes Lisp permiten hacer muchas otras cosas útiles con cuasiquotes.

Esta noción se ha transferido a otros lenguajes que apoyan la manipulación con árboles de sintaxis. Por ejemplo, la instalación de Haskell aquí es Template Haskell, y es totalmente compatible con cuasiquotación, es decir, crear plantillas y llenarlas con valores del ámbito externo. En lenguajes con sintaxis compleja (como Haskell), las citas cuasi y simples se convierten casi en la única manera sensata de manipular los árboles sintácticos.

UPD: hmm, parece que en Haskell es una característica más sofisticada que la simple sustitución. Quasiquote en Haskell parece un transformador arbitrario y un evaluador de expresiones que puede definir el usuario.


En Nemerle, una cuasi-cita es ( http://nemerle.org/metaprogramming.pdf ):

"

El metalenguaje es un lenguaje para programar tales operaciones. Por lo general, tiene su propia sintaxis para describir diversos constructos del lenguaje de los objetos.

Por ejemplo, en nuestro sistema:

<[ 1 + f (2 * x) ]>

denota el árbol de expresiones de sintaxis:

1 + f (2 * x)

Esta idea se llama cuasi-cita.

El prefijo cuasi proviene de la posibilidad de insertar valores de expresiones de metalengua en el contexto citado.

si g(y) es una expresión así, podemos escribir:

<[ 1 + $(g(y)) ]>

que describe un árbol de sintaxis, cuya segunda parte es reemplazada por el resultado de la evaluación de g(y)

"


Estas nociones existen en el lenguaje Lisp y sus variantes.

En estos idiomas, cada vez que el intérprete ve una lista (abc ... z) , la evalúa aplicando a a los otros elementos b ... z .

Si desea que una lista no se evalúe (y por lo tanto se interprete como una lista), debe citarla . Por ejemplo, ''(abc) evalúa como una lista con tres elementos, no como a aplicación de b y c . Puede ver la cita como detener la evaluación .

Ahora la cuasiquotación se comporta como una cita, excepto que puede reanudar la evaluación dentro de partes de la lista. Quasiquote con el apóstrofo retrógrado `y permite que ciertas subexpresiones queden sin comillas con el operador de coma (al menos en Scheme, no conozco otras variantes de Lisp). Por ejemplo

`(a ,(b c))

evalúa una lista con dos elementos: a , y el resultado de la evaluación de (bc) .

Esto es particularmente útil para crear plantillas, donde se llenan los agujeros al desmarcar. Ejemplo (tomado de there ):

(define (create-shipping-employee-association name) `((name ,name) (employee-id-no ,(get-next-employee-id!)) (department shipping) (hire-date ,(get-day) ,(get-month) ,(get-year))))


Una cita es solo una cadena literal. Las cuasicitaciones se "citan" en el sentido de que representan la entrada en algún sentido en lugar de ser código compilado; solo lo representan en una forma que es más fácil de manipular desde el interior del proceso de compilación (un árbol sintáctico abstracto, que puede injertarse de varias formas que son algo más seguras que operar en texto).