Clojure Динамическое связывание

Я понимаю, что следующее является плохой идеей по многим причинам. Я также понимаю, что, учитывая, что у меня количество повторений в стеке 23, естественно предположить, что я новичок в обучении программированию. Тем не менее, пожалуйста, порадуйте меня и обратите внимание на то, «как мы можем это сделать». а не "почему вы хотите это сделать / вы не хотите этого делать" аспект.

Что я хочу:

(def dog (Dog. ...))
(def cat (Cat. ...))

(with-animal dog
  (println (str "Dog: " (speak) "\n")))
(with-animal cat
  (println (str "Cat: " (speak) "\n")))

вывести:

Dog: woof
Cat: meow

В общем, я хочуwith-animal быть макросом все случаи "говорить" вызов функции отображается на объект, с которым я вызываю блок.

В частности, я не хочу писать:

(let-binding [speak (fn [] "woof")] ...)
(let-binding [speak (fn [] "meow")] ...)

Скорее, я хочу, чтобы с-животным сделатьspeak отображение функции на некоторый метод объекта, с которым я вызываю.

Есть ли чистый способ сделать это в Clojure?

Спасибо!

Ответы на вопрос(2)

Ваш ответ на вопрос