Certaines langues comme Haskell (ou Nemerle) ont des quasiquotes. Je me demande ce que signifie le "quasi" et s'il existe également des "quotes" sans la partie "quasi".
Réponses
Trop de publicités?Je crois que cette notion vient des langages Lisp.
Un programme écrit en Lisp consiste en une série de listes de listes de listes, etc., comme ceci :
(defn f [x y] (+ x y))
En raison d'une telle uniformité, il est possible de représenter et de manipuler ce code en tant que données, donc la séquence de caractères ci-dessus est interprétée comme une liste littérale. C'est une fonctionnalité très utile des Lisps, l'une de leurs caractéristiques distinctives. Pour plus de commodité, les langages Lisp permettent de 'citation' de séquences significatives, les transformant en listes au lieu de définitions et d'expressions. Cela ressemble à ceci :
'(defn f [x y] (+ x y))
Dans ce cas, il s'agit d'une liste littérale, directement disponible pour la déstructuration en utilisant des analogues des fonctions head
et tail
de Haskell et d'autres méthodes. Ainsi, 'quote' signifie 'faire une valeur littérale à partir de la liste'.
Cependant, il n'est pas commode de manipuler des listes directement avec des fonctions de type head
et tail
. Cela devient notable lorsque vous commencez à écrire des macros complexes ou même des macros génératrices de macros. C'est là qu'intervient la 'quasiquotation', littéralement 'presque une citation'. Habituellement, la quasiquotation ressemble à une citation normale (mais avec un autre symbole de citation) :
`(defn f [x y] (+ x y))
Mais c'est une chose beaucoup plus puissante. Dans une liste quasiquotée, vous pouvez remplacer des éléments arbitraires par leurs valeurs réelles provenant d'une portée externe, obtenant essentiellement quelque chose comme des modèles. Par exemple :
(let [z 10] `(defn f [x y] (+ x y ~z)))
Ici, nous attachons la valeur 10
à la variable z
et ensuite nous la substituons dans la quasi-citation. Cette expression produit :
'(defn f [x y] (+ x y 10))
C'est un exemple simple; les langages Lisp permettent de faire beaucoup d'autres choses utiles avec des quasiquotes.
Cette notion s'est étendue à d'autres langages qui prennent en charge la manipulation des arbres syntaxiques. Par exemple, la facilité en Haskell est Template Haskell, et elle prend entièrement en charge la quasiquotation, c'est-à-dire la création de modèles et leur remplissage avec des valeurs provenant d'une portée externe. Dans les langages avec une syntaxe complexe (comme Haskell), la quasi-citation et la citation normale deviennent presque la seule façon saine de manipuler les arbres syntaxiques.
MISE À JOUR : hmm, il semble qu'en Haskell, c'est une fonctionnalité plus sophistiquée que la simple substitution. La quasiquotation en Haskell ressemble à un transformateur arbitraire et à un évaluateur d'expressions qui peuvent être définis par l'utilisateur.
Ces notions existent dans le langage Lisp et ses variantes.
Dans ces langages, lorsque l'interpréteur voit une liste (a b c ... z)
, il l'évalue, en appliquant a
aux autres éléments b ... z
.
Si vous voulez qu'une liste ne soit pas évaluée (et donc interprétée comme une liste), vous devez la citer. Par exemple, '(a b c)
est évalué comme une liste avec trois éléments, et non pas comme a
appliqué à b
et c
. Vous pouvez voir la citation comme un arrêt de l'évaluation.
Maintenant, la quasi-citation se comporte comme la citation, sauf que vous pouvez reprendre l'évaluation à l'intérieur de certaines parties de la liste. Vous quasi-citez avec l'apostrophe inversé ` et vous permettez à certaines sous-expressions d'être dé-citées avec l'opérateur virgule (au moins en Scheme, je ne sais pas pour d'autres variantes de Lisp). Par exemple
`(a ,(b c))
est évalué comme une liste avec deux éléments : a
et le résultat de l'évaluation de (b c)
.
Cela est particulièrement utile pour construire des modèles, dans lesquels vous remplissez des trous en dé-citant. Exemple (pris ici) :
(define (creer-association-employe-expedition nom)
`((nom ,nom)
(numero-employe ,(obtenir-prochain-numero-employe!))
(departement expédition)
(date-embauche ,(obtenir-jour) ,(obtenir-mois) ,(obtenir-annee))))
En Nemerle, une quasi-citation est (http://nemerle.org/metaprogramming.pdf) :
"
Le métalangage est un langage pour programmer de telles opérations. Il a généralement sa propre syntaxe pour décrire diverses structures du langage objet.
Par exemple, dans notre système :
<[ 1 + f (2 * x) ]>
désigne l'arbre syntaxique de l'expression :
1 + f (2 * x)
Cette idée est appelée quasi-citation.
Le préfixe quasi vient de la possibilité d'insérer les valeurs des expressions du métalangage dans le contexte cité.
Si g(y)
est une telle expression, nous pouvons écrire :
<[ 1 + $(g(y)) ]>
qui décrit un arbre syntaxique, dont la deuxième partie est remplacée par le résultat de l'évaluation de g(y)
"
Quasi signifie en gros que vous pouvez mettre un signe dollar à l'intérieur des guillemets, et revenir au code non cité :
<[ WriteLine( $(ReadLine()) ) ]>
Cela affichera à l'exécution une chaîne entrée à la compilation (en réalité, je ne pense pas que cela fonctionnera par exemple dans Visual Studio, puisque ReadLine nécessite une entrée console; mais vous pouvez lire depuis des fichiers, un réseau, etc.)
Une citation est simplement une chaîne littérale. _Quasi_quotes sont "cités" dans le sens où ils représentent l'entrée d'une certaine manière plutôt que d'être du code compilé ; ils la représentent simplement sous une forme plus facile à manipuler à l'intérieur du processus de compilation (un arbre de syntaxe abstraite, que vous pouvez greffer de différentes manières qui sont quelque peu plus sûres que d'opérer sur du texte).