также, вы можете использовать макросы для этого случая (для развлечения и образования). Как вы можете создать простой макрос anaphori c, чтобы сделать трюк:
(defmacro make-map-ana [& keyvals]
`(-> {}
~@(map (fn [[k v]] `((fn [~'it] (assoc ~'it ~k ~v))))
(partition-all 2 keyvals))))
, как вы его используете:
user> (make-map-ana :a "some"
:b (str (:a it) " stuff"))
;;=> {:a "some", :b "some stuff"}
, который расширяется до кода замыкания следующим образом:
(-> {}
((fn [it] (assoc it :a "some")))
((fn [it] (assoc it :b (str (:a it) " stuff")))))
, поэтому он становится отражающим, передавая контекст (а именно it
) вниз по течению.
(make-map-ana :a :fun
:b it
:c it)
;;=> {:a :fun, :b {:a :fun}, :c {:a :fun, :b {:a :fun}}}
еще один способ написать этот макрос - использовать переопределение в let
bindings:
(defmacro make-map-ana [& keyvals]
`(let [~'it {}
~@(mapcat (fn [[k v]] ['it `(assoc ~'it ~k ~v)])
(partition-all 2 keyvals))]
~'it))
теперь (make-map-ana :a "some" :b (str (:a it) " stuff"))
расширился бы до следующего:
(let [it {}
it (assoc it :a "some")
it (assoc it :b (str (:a it) " stuff"))]
it)
, также получая нужный вам результат