Reader: #() params survive syntax-quote (auto-gensym names)

#(...) named its synthesized params with bare gensyms, so a #() written inside a
syntax-quote had its params qualified to the current ns by sq-symbol — and a
qualified symbol isn't a valid fn param. hiccup's compiler emits
`(let [sb# ..] (iterate! #(.append sb# %) ..)), which broke with "Unable to
resolve symbol: ns/_NNNN".

Name the params with a trailing # (auto-gensym suffix, like Clojure's p1__N#) so
syntax-quote maps them consistently and leaves them unqualified. Harmless outside
a backtick (just a regular symbol name).
This commit is contained in:
Yogthos 2026-06-15 15:15:32 -04:00
parent d223f40c91
commit c22b23fb51
3 changed files with 20 additions and 3 deletions

View file

@ -24,7 +24,14 @@
["gensym unique" "false"
"(= (gensym) (gensym))"]
["gensym# in template" "true"
"(do (defmacro m [] `(let [x# 1] x#)) (= 1 (m)))"])
"(do (defmacro m [] `(let [x# 1] x#)) (= 1 (m)))"]
# An #() lambda written inside a syntax-quote: its generated params must not be
# qualified to the ns (a qualified symbol is not a valid param). hiccup's
# compiler emits `(let [sb# ..] (run! #(.append sb# %) ..)) (jolt-nkx).
["#() inside syntax-quote" "[2 4 6]"
"(do (defmacro m [] `(mapv #(* % 2) [1 2 3])) (m))"]
["#() + auto-gensym share in template" "\"ab\""
"(do (defmacro m [] `(let [sb# (StringBuilder.)] (mapv #(.append sb# %) [\"a\" \"b\"]) (.toString sb#))) (m))"])
# Core macros ported from Janet to the Clojure overlay (jolt-1j0 phase 3,
# jolt-core/clojure/core/30-macros.clj).