for the past few weeks I’ve been working with “core.async” in Clojure and Clojurescript, wondering if it is a good idea to use outside bound symbols inside a go
as there is a pool of threads and possibly any of these could use the bound symbols. It works evaluating it, but macroexpansion does not work - see the following snippets
I guess it should work without problems. The x
is immutable and wont change by concurrent threads. Using an atom
as x
for mutable data should also work cause its an atom
XD E.g. an object ref would not work of course or could make problems!
(let [x 5]
(clojure.core.async/go
(println x)))
;; => 5
;; nil
(clojure.walk/macroexpand-all
'(let [x 5]
(clojure.core.async/go
(println x))))
;; => Syntax error macroexpanding clojure.core.async/go at (your_project.cljc:93:3).
;; Could not resolve var: x
It seems to work, but is it a bad idea and why?
Anyone can explain why macroexpansion does not work?
macroexpand-all
is not a high-fidelity expander. It uses a basic process that works for simple macros, but it doesn't do everything the actual compiler does. Notably, it does not curate the &env
map that bindings should introduce. I assume core.async needs to look at &env
to determine whether a binding is local or a var.
So, you shouldn't expect macroexpand-all
to work here, but there's nothing wrong with writing code of this sort.