I tried it in ClojureScript and I did get the same error as your did. I believe 
this is because the go-macro doesn't handle the case-statement correctly (or, 
rather, not at all). Switching from (case key ...) to (condp = key ...) however 
appears to do the trick (along with all the other awkward namespacing stuff):

(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]
                         `(cljs.core/let [~res ~ressym] ~@body)))
        cases (if default-case (butlast cases) cases)
        case-body (apply concat (for [[key [args & body]] (partition 2 cases)]
                                  [key `(cljs.core/let [~args ~argssym] 
~@body)]))
        case-body (if default-case
                    (conj (vec case-body) default-case)
                    case-body)]
    `(cljs.core/let [ch# ~ch
                     ~ressym (cljs.core.async/<! ch#)]
       (if (cljs.core/and (cljs.core/vector? ~ressym) (cljs.core/seq ~ressym)) 
;; <- still problematic
         (cljs.core/let [~keysym (cljs.core/first ~ressym)
                         ~argssym (cljs.core/next ~ressym)]
           (cljs.core/condp = ~keysym ~@case-body))
         ~default-case))))

However, this still gives an error if you put :foobar onto the channel. This, 
too, appears to be a core.async bug: in the line highlighted above, *both* 
arguments to "and" get evaluated, regardless of whether the first argument is 
false or not.


Am Dienstag, 22. Juli 2014 20:46:45 UTC+2 schrieb Tom Locke:
> On Tuesday, 22 July 2014 16:42:00 UTC+2, Kevin Marolt  wrote:
> > Not sure if I understood the initial question correctly, but isn't the 
> > following sort of what you wanted?
> 
> Yes that's exactly what I was after, although that is Clojure, right? I've 
> tried it in ClojureScript (not much to change - just requiring the right 
> namespaces / macros) and it doesn't work. I get:
> 
>     No implementation of method: :emit-instruction of protocol: 
> #'cljs.core.async.impl.ioc-macros/IEmittableInstruction found for class: 
> cljs.core.async.impl.ioc_macros.Jmp
> 
> I've tried playing around moving the <! and the (recur) outside of the 
> on-dispatch macro, and, while I can avoid the above error and get it to 
> compile, the behaviour of the test code makes no sense at all. It seems like 
> mixing the go macro with your own macros is very fragile in cljs.
> 
> Tom

-- 
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to