Вы могли бы top-section
развернуть до специально созданной формы let
, связывающей символ link
с частичным применением исходной функции link
к первому аргументу формы top-section
:
(defmacro top-section [n s & forms]
`(let [~'link (partial ~'link ~n)]
(prn ~s) ; handle s in whichever way is appropriate
~@forms))
;; for the sake of example
(defn link [n s] (prn n s))
Взаимодействие REPL (напечатано три строки, nil
возвращено):
user> (top-section 1 "start of text"
(link "more text")
(link "still more"))
"start of text"
1 "more text"
1 "still more"
nil
Если top-section
s может потребоваться вложение, вы можете использовать более сложный top-section
, который заботитсязахватить «область имен» link
:
(defmacro top-section [n s & forms]
(let [qlink (symbol (name (.. (resolve 'link) ns name)) "link")]
`(let [~'link (partial ~qlink ~n)]
(prn ~s)
~@forms)))
На REPL:
user> (top-section 1 "start of text"
(link "more text")
(link "still more")
(top-section 2 "inner section"
(link "etc.")))
"start of text"
1 "more text"
1 "still more"
"inner section"
2 "etc."
nil
(Вполне возможно, совершенно ненужное усложнение следует - настраиваемыйвариант top-section
- надеюсь, это несколько приятнее, если не полезно ...)
Кстати, у вас есть небольшой фиксированный набор функций, которые вы захотите обработать таким образом или выполнитеВы думаете, что это может расшириться / оказаться большим?В последнем случае вы могли бы top-section
выполнить одно и то же для всех символов, хранящихся, например, где-нибудь в атоме:
(def top-section-syms (atom #{'link}))
(defmacro top-section [n s & forms]
(let [nsym (gensym "n")
qs (for [s @top-section-syms]
[s (symbol (name (.. (resolve s) ns name)) (name s))])]
`(let [~nsym ~n
~@(->> (for [[s q] qs]
[s `(partial ~q ~nsym)])
(apply concat))]
(prn ~s)
~@forms)))
При REPL:
user> (swap! top-section-syms conj 'prn)
#{prn link}
user> (top-section 1 "start of text"
(link "more text")
(link "still more")
(top-section 2 "inner section"
(link "etc.")
(prn "and another fn...")))
"start of text"
1 "more text"
1 "still more"
"inner section"
2 "etc."
2 "and another fn..."
nil
Операцияswap!
ввод нового символа может быть предварительно проверен простой функцией / макросом (register-top-section-symbol
?).