Совместное использование функций между пространствами имен в Clojure

Я вполне могу подойти к этому неправильно, поэтому, пожалуйста, прости меня за мою наивность:

Чтобы изучить Clojure, я начал переносить свою клиентскую библиотеку OAuth для Python на Clojure. Я делаю это, оборачивая clj-http так же, как оборачиваю запросы Python в библиотеку Python. Кажется, до сих пор это работает очень хорошо, и мне действительно нравится наблюдать за реализацией в Clojure.

Однако я столкнулся с проблемой: я планирую поддерживать OAuth 1.0 и 2.0 и разделить соответствующие функции на два файла: oauth1.clj и oauth2.clj. Теперь каждый файл в идеале должен предоставлять набор функций, которые соответствуют HTTP-глаголам.

(ns accord.oauth2)

...

(defn get
  [serv uri & [req]]
  ((:request serv) serv (merge req {:method :get :url uri})))

Эти функции будут практически идентичны и фактически сейчас полностью идентичны между oauth1.clj и oauth2.clj. Моей первой реакцией было перенести эти функции в core.clj, а затем потребовать их в соответствующих пространствах имен OAuth (oauth1, oauth2), чтобы избежать написания одного и того же кода дважды.

Это нормально, если я использую упомянутые функции в файле, то есть oauth1.clj или oauth2.clj. Но допустим, что мы хотим использовать эту библиотеку, как я собираюсь (здесь, в REPL, в качестве альтернативы вашей программе), что-то вроде этого:

=> (require '[accord.oauth2 :as oauth2])  ;; require the library's oauth2 namespace

...

=> (oauth2/get my-service "http://example.com/endpoint")  ;; use the HTTP functions

Варoauth2/get не найден, потому что вытягивание его в пространство имен только в oauth2.clj, похоже, не раскрывает его так, как если бы оно было в этом пространстве имен Я не хочу оборачивать их большим количеством функций, потому что это в основном побеждает цель; функции так просты (они просто обернутьrequest функция) Я бы написал их в трех местах, по сути, если бы я это сделал.

Я уверен, что не правильно понимаю пространства имен в Clojure и, более того, возможно, идиоматически думает о проблемах абстракции и совместном использовании кода.

Так что мне интересно, что это за идиоматическое решение? Я поступаю об этом совершенно неправильно?

Редактировать:

Вот упрощение проблемы:https://gist.github.com/maxcountryman/5228259

Обратите внимание, что цель состоит в том, чтобы написать функции глагола HTTP один раз. Им не нужны специальные типы отправки или что-то подобное. Они уже в порядке, как они. Проблема в том, что они не подвергаютсяaccord.oauth1 или жеaccord.oauth2то есть когда ваша программа требуетaccord.oauth2 например.

Если бы это был Python, мы могли бы просто импортировать такие функции:from accord.core import get, post, put, ... вaccord.oauth1 а такжеaccord.oauth2 а потом, когда мы использовалиaccord.oauth1 В модуле у нас будет доступ ко всем этим импортированным функциям, например,import accord.oauth2 as oauth2 ...oauth2.get(...).

Как мы можем сделать это в Clojure или как идиоматически предусмотреть этот вид СУХОЙ абстракции?

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

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