In Clojure müssen Sie gensym
verwenden, um Symbole für den internen Gebrauch in Ihren Makros zu erstellen, um sie hygienisch zu halten. Manchmal müssen Sie jedoch das gleiche Symbol in verschachtelten Syntax-Anführungszeichen verwenden. Zum Beispiel, wenn ich einen Wert auf ein Symbol mit let
und drucken Sie es dreimal in einer entrollten Schleife binden möchten, würde ichKoordinieren von Auto-Gensym in verschachtelten Syntax-Anführungszeichen in Clojure
`(let [x# 1]
[email protected](repeat 3
`(println x#)))
tun Aber das würde produzieren
(clojure.core/let [x__2__auto__ 1]
(clojure.core/println x__1__auto__)
(clojure.core/println x__1__auto__)
(clojure.core/println x__1__auto__))
x#
a erzeugt anderes Symbol in der let
Form als in der println
Formen darin verschachtelt - weil sie aus verschiedenen Syntax-Anführungszeichen erstellt wurden.
es zu lösen, kann ich das Symbol vorher erzeugen und an die Syntax-Zitate injizieren:
(let [x (gensym)]
`(let [~x 1]
[email protected](repeat 3
`(println ~x)))
)
Dies wird das richtige Ergebnis, mit dem gleichen Symbol erzeugen überall gebraucht:
(clojure.core/let [G__7 1]
(clojure.core/println G__7)
(clojure.core/println G__7)
(clojure.core/println G__7))
Jetzt, während es das richtige Ergebnis produziert, sieht der Code selbst hässlich und ausführlich aus. Ich mag es nicht, ein Symbol "deklarieren" zu müssen, und die Injektionssyntax lässt es so aussehen, als käme es von außerhalb des Makros oder irgendwo dazwischen berechnet. Ich möchte in der Lage sein, die Auto-Gensym Syntax zu verwenden, die klarstellt, dass das Makro-interne Symbole sind.
Also, gibt es eine Möglichkeit, Auto-Gensym mit verschachtelten Syntax-Anführungszeichen zu verwenden und sie das gleiche Symbol zu erzeugen?
Danke. Ich kann nicht normal unter Angabe der Druck Ausdruck zu arbeiten, aber ich nehme an, es sowieso für komplexere Makros lästig werden werde ... –
Wenn Sie etwas tun, ich empfehlen \ 'println verwenden, nicht‚println - Ersteres unterliegt keiner Namensaufzeichnung, wenn der Makrobenutzer einen ungewöhnlichen Namespace oder lexikalischen Kontext hat. – amalloy
guter Punkt! Ich werde bearbeiten, um das zu beheben –