Причина, по которой `(~f ~@(map ~s ~symbols))
не работает, заключается в том, что компилятор перекрывает ненужные unquote
(~
) внутри unquote-splicing
(~@
). unquote-splicing
заключает в кавычки внешний syntax-quote
(`
), поэтому внутренние два unquote
не имеют совпадений syntax-quote
, поэтому вы получили ошибку «unbound».
То, что вы хотите сделать, - это сначала (map s symbols)
вычислить, чтобы получить последовательность операндов, затем передать полученный результат функции (~f
); поэтому правильная версия:
(defmacro with-params [s f & symbols] `(~f ~@(map s symbols)))
Вы можете легко проверить это с помощью:
(macroexpand '(with-params {:a 1 :b 2 :c 5} * :a :b :c)) ;; (* 1 2 5)
(with-params {:a 1 :b 2 :c 5} * :a :b :c) ;; 10