Skip to content

Instantly share code, notes, and snippets.

@daveray
Created August 25, 2013 03:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daveray/6331871 to your computer and use it in GitHub Desktop.
Save daveray/6331871 to your computer and use it in GitHub Desktop.
rxjava Func* and Action* generators
(defmacro ^:private reify-callable
"Reify a bunch of Func* interfaces
prefix fully qualified interface name. numbers will be appended
arities vector of desired arities
f the function to execute
"
[prefix arities f]
(let [f-name (gensym "rc")]
`(let [~f-name ~f]
(reify
~@(mapcat (clojure.core/fn [n]
(let [ifc-sym (symbol (str prefix n))
arg-syms (map #(symbol (str "v" %)) (range n))]
`(~ifc-sym
(~'call ~(vec (cons 'this arg-syms))
~(cons f-name arg-syms)))))
arities) ))))
(defn fn*
"Given function f, returns an object that implements rx.util.functions.Func0-9
by delegating to the given function.
See:
http://netflix.github.io/RxJava/javadoc/rx/util/functions/Func0.html
"
[f]
(reify-callable "rx.util.functions.Func" [0 1 2 3 4 5 6 7 8 9] f))
(defn fnN*
"Given function f, returns an object that implements rx.util.functions.FuncN
by delegating to the given function.
Unfortunately, this can't be included in fn* because of ambiguities between
the single arg call() method and the var args call method.
See:
http://netflix.github.io/RxJava/javadoc/rx/util/functions/FuncN.html
"
[f]
(reify rx.util.functions.FuncN
(call [this objects]
(apply f objects))))
(defmacro fn
"Like clojure.core/fn, but returns the appropriate rx.util.functions.Func*
interface.
Example:
(.map my-observable (rx/fn [a] (* 2 a)))
"
[& fn-form]
; TODO at the moment, returns something that implements Func0-9. Introspect on arg list
; to only reify the exact interfaces needed.
; have to qualify fn*. Otherwise bad things happen with the low-level fn* in clojure
`(com.netflix.indigena.rx.fn/fn* (clojure.core/fn ~@fn-form)))
(defn action*
"Given function f, returns an object that implements rx.util.functions.Action0-9
by delegating to the given function.
See:
http://netflix.github.io/RxJava/javadoc/rx/util/functions/Action0.html
"
[f]
(reify-callable "rx.util.functions.Action" [0 1 2 3] f))
(defmacro action
"Like clojure.core/fn, but returns the appropriate rx.util.functions.Action*
interface.
Example:
(.map my-observable (rx/action [a] (* 2 a)))
"
[& fn-form]
; TODO at the moment, returns something that implements Action0-3. Introspect on arg list
; to only reify the exact interfaces needed.
`(action* (clojure.core/fn ~@fn-form)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment