Funkcje udostępniania między przestrzeniami nazw w Clojure

Być może dobrze podejdę do tego w niewłaściwy sposób, więc proszę wybacz mi moją naiwność:

Aby nauczyć się Clojure, zacząłem przenosić moją bibliotekę klienta OAuth dla Pythona do Clojure. Robię to, owijając clj-http w ten sam sposób, w jaki zawijam Python Requests w bibliotece Pythona. Wydaje się, że jak dotąd działa to całkiem nieźle i naprawdę cieszę się widząc, jak wdrożenie w Clojure ożywa.

Mam jednak problem: planuję obsługiwać zarówno OAuth 1.0, jak i 2.0 i podzielić odpowiednie funkcje na dwa pliki: oauth1.clj i oauth2.clj. Teraz każdy plik powinien idealnie ujawnić zestaw funkcji, które odpowiadają czasownikom HTTP.

(ns accord.oauth2)

...

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

Funkcje te będą zasadniczo identyczne iw rzeczywistości są teraz całkowicie identyczne między oauth1.clj i oauth2.clj. Moją pierwszą reakcją było przeniesienie tych funkcji do core.clj, a następnie zażądanie ich w odpowiednich przestrzeniach nazw OAuth (oauth1, oauth2), aby uniknąć dwukrotnego pisania tego samego kodu.

Jest to w porządku, o ile używam określonych funkcji w pliku, tj. Oauth1.clj lub oauth2.clj. Ale powiedzmy, że chcemy korzystać z tej biblioteki w zamierzony sposób (tutaj w REPL, alternatywnie twój program), coś takiego:

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

...

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

Varoauth2/get nie został znaleziony, ponieważ wyciągnięcie go do przestrzeni nazw w samym oauth2.clj nie wydaje się ujawniać go tak, jakby był w tej przestrzeni nazw. Nie chcę ich owijać większą liczbą funkcji, ponieważ to w zasadzie pokonuje cel; funkcje są tak proste (po prostu zawijająrequest funkcja) Pisałbym je w trzech miejscach, zasadniczo, gdybym to zrobił.

Jestem pewien, że właściwie nie grokuję przestrzeni nazw w Clojure, a poza tym być może ogólny sposób myślenia o problemach z abstrakcją i dzieleniu się kodem idiomatycznie.

Zastanawiam się, co to jest idiomatyczne rozwiązanie? Czy idę w tym całkowicie niewłaściwie?

Edytować:

Oto uproszczenie problemu:https://gist.github.com/maxcountryman/5228259

Pamiętaj, że celem jest jednorazowe napisanie funkcji czasownika HTTP. Nie potrzebują specjalnych rodzajów wysyłki ani czegoś takiego. Są już w porządku, jak są. Problem polega na tym, że nie są narażeniaccord.oauth1 lubaccord.oauth2, tj. kiedy program wymagaaccord.oauth2 na przykład.

Gdyby to był Python, moglibyśmy po prostu zaimportować takie funkcje:from accord.core import get, post, put, ... waccord.oauth1 iaccord.oauth2 a potem, kiedy użyliśmyaccord.oauth1 moduł mielibyśmy dostęp do wszystkich zaimportowanych funkcji, np.import accord.oauth2 as oauth2 ...oauth2.get(...).

Jak możemy to zrobić w Clojure lub jak powinniśmy idiomatycznie zapewnić tego rodzaju abstrakcję DRY?

questionAnswers(3)

yourAnswerToTheQuestion