Gemeinsame Nutzung von Funktionen zwischen Namespaces in Clojure

Möglicherweise gehe ich das falsch an, bitte verzeihen Sie mir meine Naivität:

Um Clojure zu lernen, habe ich begonnen, meine OAuth-Clientbibliothek für Python nach Clojure zu portieren. Ich mache das, indem ich clj-http ähnlich wie Python-Requests in die Python-Bibliothek einbinde. Dies scheint bisher ziemlich gut zu funktionieren, und ich freue mich sehr, dass die Implementierung in Clojure zum Leben erweckt wird.

Ich habe jedoch ein Problem: Ich plane, sowohl OAuth 1.0 als auch 2.0 zu unterstützen und habe die entsprechenden Funktionen in zwei Dateien aufgeteilt: oauth1.clj und oauth2.clj. Jetzt sollte jede Datei im Idealfall eine Reihe von Funktionen verfügbar machen, die HTTP-Verben entsprechen.

(ns accord.oauth2)

...

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

Diese Funktionen werden im Wesentlichen identisch sein und sind derzeit zwischen oauth1.clj und oauth2.clj völlig identisch. Meine erste Reaktion bestand darin, diese Funktionen in core.clj zu verschieben und sie dann in den jeweiligen OAuth-Namespaces (oauth1, oauth2) zu fordern, um zu vermeiden, dass derselbe Code zweimal geschrieben wird.

Dies ist in Ordnung, solange ich die in der Datei angegebenen Funktionen verwende, d. H. Oauth1.clj oder oauth2.clj. Aber nehmen wir an, wir möchten diese Bibliothek so verwenden, wie ich es beabsichtige (hier in der REPL, alternativ in Ihrem Programm):

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

...

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

Die varoauth2/get wird nicht gefunden, da das Ziehen in den Namespace in oauth2.clj allein ihn nicht offen zu legen scheint, als befände er sich tatsächlich in diesem Namespace. Ich möchte sie nicht mit mehr Funktionen umhüllen, weil dies im Grunde den Zweck zunichte macht. Die Funktionen sind so einfach (sie wickeln nur einrequest Funktion) Ich würde sie im Wesentlichen an drei Stellen schreiben, wenn ich das tun würde.

Ich bin mir sicher, dass ich Namespaces in Clojure nicht richtig ausgrabe und darüber hinaus vielleicht die allgemeine Art, über Abstraktionsprobleme und die gemeinsame Nutzung von Code idiomatisch nachzudenken.

Also frage ich mich, was die idiomatische Lösung dafür ist? Gehe ich das völlig falsch an?

Bearbeiten:

Hier ist eine Vereinfachung des Problems:https://gist.github.com/maxcountryman/5228259

Beachten Sie, dass das Ziel darin besteht, die HTTP-Verbfunktionen einmal zu schreiben. Sie brauchen keine speziellen Versandarten oder ähnliches. Es geht ihnen schon gut, wie sie sind. Das Problem ist, dass sie nicht ausgesetzt sindaccord.oauth1 oderaccord.oauth2wenn Ihr Programm dies erfordertaccord.oauth2 zum Beispiel.

Wenn dies Python wäre, könnten wir die Funktionen einfach so importieren:from accord.core import get, post, put, ... inaccord.oauth1 undaccord.oauth2 und dann als wir das benutztenaccord.oauth1 Modul hätten wir Zugriff auf alle diese importierten Funktionen, z.import accord.oauth2 as oauth2 ...oauth2.get(...).

Wie können wir dies in Clojure tun oder wie sollten wir idiomatisch für diese Art von DRY-Abstraktion sorgen?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage