27 votes

Comment fonctionne la citation de syntaxe de clojure?

Divers caractères spéciaux en clojure sont des abréviations pour des choses

(quote (a b)) est le même que '(a b)

comme vous pouvez le voir par l'évaluation:

user> ''(a b)
(quote (a b))

Cela semble être la syntaxe comme abréviation, ce qui me semble une bonne idée.

Mais la syntaxe-citation ` , semble spécial. Je ne peux pas penser à ce qui serait l'équivalent de

`(a b)

J'aurais deviné quelque chose comme (syntax-quote (a b)) , mais ça ne fonctionne pas, et si j'ai un peu deviné tort, je ne peux pas savoir ce que c'est vraiment appelé.

user> '`(a b)
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/a)) (clojure.core/list (quote user/b))))

C'est un peu déconcertant.

Sans doute le lecteur à faire quelque chose de spécial, peut-être parce qu'il a besoin de connaître les espaces de noms?

Fait intéressant, la syntaxe utilisée dans la syntaxe-citation ne fonctionne pas comme je l'attendais:

user> '~a
(clojure.core/unquote a)
user> '~@a
(clojure.core/unquote-splicing a)
user> '~'a
(clojure.core/unquote (quote a))

sauf pour celui-ci:

user> 'a#
a#

Qui j'aurais pensé que cela produit quelque chose comme (unquote (gensym "a"))

Je ne réalise que je suis peut être un peu faible ici, et devrait juste d'aller lire le code. Si personne ne croit en expliquant ce qui se passe ou de donner une référence, quelqu'un peut me donner un indice sur la façon de trouver le code et ce que vous recherchez?

29voto

Brian Carper Points 40078

Je ne pense pas qu'il y a une syntaxe devis équivalent de l' quote fonction.

Le Clojure lecteur est (pour l'instant) écrit en Java. L' SyntaxQuoteReader classe src/jvm/clojure/lang/LispReader.java dans le Clojure source est probablement ce que vous aurez envie de le lire. Il semble plutôt complexe. Vous pouvez voir la construction des listes de ce genre (seq (concat ...)) - il.

                ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));

Il est commun pour le lecteur de ne pas retourner simple Clojure code, mais plutôt de faire la bonne chose en Java atterrir immédiatement. Par exemple '[1 2 3] ne donne pas le code équivalent en Clojure (vector 1 2 3). Peut-être qu'il pourrait travailler de cette façon en quelque sorte, mais il ne le fait pas. Le lecteur crée et renvoie le vecteur de l'objet lui-même.

De même, l' SyntaxQuoteReader un peu de magie dans Java immédiatement pour résoudre le symbole de espaces de noms et de créer gensyms lui-même et il retourne quelques mutilé et l'air compliqué Clojure code qui fait la bonne chose, mais n'est pas forcément facile pour un homme de lire. Si c'est comme cela parce qu'il a à être, ou parce qu'il est plus facile de le faire de cette façon en Java, ou pour la performance ou pour une autre raison, je ne sais pas. De même, je ne sais pas si quasiquote pourrait exister comme une simple macro/forme spéciale en Clojure et n'est pas, ou si elles n'existent pas du tout. Je ne vois pas pourquoi il ne pouvait pas bien.

WrappingReader dans le même fichier, c'est la classe qui gère ' (plain old quote). Vous pouvez voir qu'elle encapsule tout ce que vous passer dans une liste contenant le symbole quote plus votre argument. C'est beaucoup plus simple. Notez que cette classe gère également l' @, de sorte qu' '@foo n'retour (deref foo).

Ce fil pourrait faire plus de lumière.

Modifier

Voici une preuve de concept, quasiquote macro. Notez que ce code est en invoquant et d'abuser de Clojure internes d'une manière horrible. S'il vous plaît ne pas l'utiliser pour quoi que ce soit.

user> (defmacro quasiquote [x]
        (let [m (.getDeclaredMethod clojure.lang.LispReader$SyntaxQuoteReader 
                                    "syntaxQuote" 
                                    (into-array [Object]))]
          (.setAccessible m true)
          (.invoke m nil (into-array [x]))))
#'user/quasiquote
user> (let [x 123] `(x 'x ~x))
(user/x (quote user/x) 123)
user> (let [x 123] (quasiquote (x 'x ~x)))
(user/x (quote user/x) 123)

3voto

Arthur Ulfeldt Points 45059

Vous semblez avoir une bonne compréhension de la syntaxe des macros pour commencer donc il n'y a pas trop que je puisse ajouter.

il y a un peu de couverture sur les forums de clôture de programmation . et vous pouvez à votre guise lire le code ici, consultez la ligne 352

2voto

amalloy Points 29125

hiredman a implémenté une version entièrement clojure de syntax-quote . Pas pour les âmes sensibles, mais une bonne preuve de concept.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X