Hi Paul,
I tired several things, but I couldn't figure out the `apply` problem with the Function wrapper around publishized functions. I came up with the following workaround. This macro creates a function that publishes its result on bus when it is called. You can also use it as the target of a `subscribe`. It's not the prettiest, but it does the job and I thought I'd share:
;; ------------ montoux/tools/pubsub/macros.clj ------------
(ns montoux.tools.pubsub.macros)
(defmacro defnp
"Like defn, but creates a publishized version of the function with the supplied
name. The orginal function will be defined with name__nnnn where nnnn is a
random number. The symbol denoting the original function can be found in the
function's meta under :publishized-fn."
[name bus & fdecl]
(let [[m fdecl] (if (string? (first fdecl))
[{:doc (first fdecl)} (rest fdecl)]
[{} fdecl])
name* (gensym (str (clojure.core/name name) "__"))]
`(do
(defn ~name* ~@fdecl)
(defn ~name [& args#]
(let [r# (apply ~name* args#)
t# (shoreleave.pubsubs.protocols/topicify ~name)]
(shoreleave.pubsubs.protocols/publish ~bus t# r#)
r#)))))
(defmacro defp
[name bus & decl]
`(do
(def ~name ~@decl)
(shoreleave.pubsubs.protocols/publishize ~name ~bus)
~name))
;; ------------ montoux/application.cljs ------------
;;
;; this will print the following to the console:
;;
;; f1 arg: {:new 10, :old 0}
;; f2 arg: 52
(ns montoux.application
(:require [shoreleave.pubsubs.simple :as simplebus]
[shoreleave.pubsubs.protocols :as pubsub])
(:require-macros [montoux.tools.pubsub.macros :as ps]))
(def bus (simplebus/bus))
(ps/defp a bus (atom 0))
(ps/defnp f1 bus [arg]
(.log js/console "f1 arg:" (pr-str arg))
(+ 42 (:new arg)))
(ps/defnp f2 bus [arg]
(.log js/console "f2 arg:" (pr-str arg))
(* 2 arg))
(pubsub/subscribe bus a f1)
(pubsub/subscribe bus f1 f2)
(reset! a 10)