core.async: “Can’t recur here” in ClojureScript but OK in Clojure

With the latest core.async and ClojureScript (core.async "0.1.303.0-886421-alpha" and clojurescript "0.0-2202" as well as the older core.async "" and clojurescript "0.0-2173"), the following function compiles just fine in Clojure but fails in ClojureScript:

(defn cljs-cannot-recur! []
  (go-loop [v nil]
    (when-let [next-val (<! (timeout 300))]
      (recur next-val))))

The error in ClojureScript is

clojure.lang.ExceptionInfo: Can't recur here at line 23 /my/path/core.cljs ::
  {:tag :cljs/analysis-error, :file "/my/path/core.cljs", :line 23, :column 7}
             core.clj:4403 clojure.core/ex-info
             ... // very long stacktrace of 0 value

Workaround: replace (go-loop ..) with (go (loop ..)).

Another fun fact: ClojureScript’s core.async lacks (at least) alt! (I did work around it by using alts! so it is not a show-stopper but still the difference is irritating and I fail to understand why it is missing.)

Oh, joy!

Published by Jakub Holý

I’m a JVM-based developer since 2005, consultant, and occasionally a project manager, working currently with Iterate AS in Norway.