I may very well be approaching this in the wrong way, so please forgive me of my naiveté:
In order to learn Clojure I've begun porting my OAuth client library for Python to Clojure. I'm doing this by wrapping clj-http much in the same way I wrap Python Requests in the Python library. This seems to be working pretty well so far and I'm really enjoying seeing the implementation come to life in Clojure.
However I have run into a problem: I'm planning to support both OAuth 1.0 and 2.0 and have split the respective functions into two files: oauth1.clj and oauth2.clj. Now, each file should ideally expose a set of functions which correspond to HTTP verbs.
(ns accord.oauth2)
...
(defn get
[serv uri & [req]]
((:request serv) serv (merge req {:method :get :url uri})))
These functions will be essentially identical and in fact right now are completely identical between oauth1.clj and oauth2.clj. My first reaction was to move these functions into core.clj and then require them in the respective OAuth namespaces (oauth1, oauth2) so as to avoid writing the same code twice.
This is fine so long as I use the referred functions in the file, i.e. oauth1.clj or oauth2.clj. But let's say we want to use this library as I'm intending (here in the REPL, alternatively your program), something like this:
=> (require '[accord.oauth2 :as oauth2]) ;; require the library's oauth2 namespace
...
=> (oauth2/get my-service "http://example.com/endpoint") ;; use the HTTP functions
The var oauth2/get is not found because pulling it into the namespace in oauth2.clj alone doesn't seem to expose it as though it were actually in that namespace. I don't want to wrap them with more functions, because that basically defeats the purpose; the functions are so simple (they just wrap a request function) I would be writing them in three places, essentially, if I were to do that.
I'm sure I'm not grokking namespaces in Clojure properly and moreover maybe the general way of thinking about abstraction problems and code sharing idiomatically.
So I'm wondering what the idiomatic solution to this is? Am I going about this completely the wrong way?
Edit:
Here's a simplification of the problem: https://gist.github.com/maxcountryman/5228259
Note that the the goal is to write the HTTP verb functions one time. They don't need special dispatch types or something like that. They're already fine as they are. The issue is that they aren't exposed from accord.oauth1 or accord.oauth2, i.e. when your program requires accord.oauth2 for instance.
If this were Python we could just import the functions like this: from accord.core import get, post, put, ... into accord.oauth1 and accord.oauth2 and then when we used the accord.oauth1 module we would have access to all those imported functions, e.g. import accord.oauth2 as oauth2 ... oauth2.get(...).
How can we do this in Clojure or how should we idiomatically provide for this kind of DRY abstraction?
accord.corenamespace. Then theaccord.oauth1andaccord.oauth2namespaces require these functions by referring :all fromaccord.coreinto their respective namespaces. The problem with this is you can't then requireaccord.oauth2, say in the REPL or from your program, and then use the HTTP functions in this way:accord.oauth2/get. If the functions were actually written, twice, in each file, that would work. I'm trying to avoid that, however. :)accord.oauth-common, and import that to get the common functions, or 2) just usedefto re-bind the functions you want in each namespace (rather than fully re-declaring them), e.g.(def get oauth1/get). I'd personally go with the first option.(ns testing.bar (:use [test core baz]))inbar.clj.