API wrapper for Clojure I wanted to wrap the jkeymaster library in a Clojure wrapper (for my own use, but perhaps also to save others some time). I'm just learning Clojure so I'm still not quite sure what "idiomatic libraries/APIs" look like. In Ruby, I would have created an object with methods, but in one of the clojure books they recommended letting users manage state themselves, so I have function that creates a provider, and this provider must then be passed to the register function.

Here's first an example of usage:

(ns keymaster.core
  (:require [keymaster.keymaster :as km]))
(defn -main
  "I don't do a whole lot ... yet."
  [&amp; args]
  (km/register (km/provider) "control shift 1" #(println "hi")))


And here is the full text of the "library".

(ns keymaster.keymaster
  (:gen-class)
  (:use (com.tulskiy.keymaster.common)))

(defn provider []
  "Gets and initiates a keymaster provider, which must be passed to register to register shortcuts"
  (let [provider (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)]
    (.init provider)
    provider))

(defn- conv-keystroke [x]
  "Takes keystroke in the form \"control shift 1\" and returns a Keystroke class"
  (javax.swing.KeyStroke/getKeyStroke x))

(defn- conv-listener [f]
  "Takes a function with one argument, which will get passed the keycode, and creates a listener
   Todo: How to accept a function with or without a parameter to accept hotKey?"
   (proxy [com.tulskiy.keymaster.common.HotKeyListener] [] (onHotKey [hotKey] (f))))

(defn register
  [provider shortcut listener]
  "Registers a shortcut on provider, which will trigger listener (with one argument)"
  (let [k (conv-keystroke shortcut)
        l (conv-listener listener)]
    (.register provider k l)))


In addition to any general style feedback, both about the coding, and the design of the API, I'm also wondering if there is any way to have conv-listener accept either a 0 or 1-arity function. Right now I made the choice of accepting a 0-arity function, but if someone wanted to pass a 1-arity function, where the first argument would be the name of the keycode called (hotKey), which I would call with (f hotKey), I would have to rewrite... Possible to allow both? (1-arity is inconvenient for anonymous functions where we really don't need it - which I suspect is most of the time, since we can bind different hotkeys to different listeners).
As a wrapper goes I think this looks fine. The feedback I do have is that I wouldn't use let as often as you do and would use the treading macro (-&gt; ...) instead. 

For example:

(-&gt; (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)
      .init)


does the same as 

(let [provider (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)]
  (.init provider)
  provider)


and it's easier to read and shorter. You could also do it this way:

(.init (com.tulskiy.keymaster.common.Provider/getCurrentProvider true))