Not sure if I understood the initial question correctly, but isn't the 
following sort of what you wanted?

;; ======

(require '[clojure.core.async :as async])

(defmacro dispatch-on [ch & cases]
  (let [argssym (gensym "args__")
        keysym (gensym "key__")
        ressym (gensym "res__")
        default-case (when (odd? (count cases)) (last cases))
        default-case (when default-case
                       (let [[[res] & body] default-case]
                         `(let [~res ~ressym] ~@body)))
        cases (if default-case (butlast cases) cases)
        case-body (apply concat (for [[key [args & body]] (partition 2 cases)]
                                  [key `(let [~args ~argssym] ~@body)]))
        case-body (if default-case
                    (conj (vec case-body) default-case)
                    case-body)]
    `(let [ch# ~ch
           ~ressym (async/<! ch#)]
       (if (and (vector? ~ressym) (seq ~ressym))
         (let [~keysym (first ~ressym)
               ~argssym (next ~ressym)]
           (case ~keysym ~@case-body))
         ~default-case))))

(def ch (async/chan))         
         
(async/go 
  (loop []
    (dispatch-on ch
      :add ([a b] (println a "plus" b "is" (+ a b)) (recur))
      :sqrt ([x] (println "The square root of" x "is" (Math/sqrt x)) (recur))
      ;default
      ([x] (when-not (nil? x)
             (println "unknown operation:" x)
             (recur))))))

(async/put! ch [:add 40 2])
(async/put! ch [:sqrt 1764])
(async/put! ch [:foo :bar])
(async/put! ch :foobar)
(async/close! ch)    

;; =====

This prints:

40 plus 2 is 42 
The square root of 1764 is 42.0
unknown operation: [:foo :bar]
unknown operation: :foobar

While it's true that the go-macro can't peek beyond a function's boundaries, it 
actually *does* perform macroexpansion before applying its transformations.


Cheers,
Kevin


-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to