Goal: I'm trying to make a macro which takes as an input something like the following:
(cb-chan (.readFile "/path/to/file" "utf8" _))
and returns as an output something like the following:
(go (let [c (chan 1)
rep (.readFile "path/to/file" "utf8" (>? c)] ; >? is a function that I defined elsewhere that jams the result of a callback into a channel
rep
(<! c))))
Notice that the _
in the original input is being replaced by special callback (defined elsewhere). This callback jams its result into a channel, which is then retrieved and returned at end of the go block.
Attempt:
(defmacro cb-chan [func]
`(cljs.core.async.macros/go
(let [~'c (cljs.core.async/chan 1)]
~'rep (replace (quote {~'_ (cljs-async-patterns.core/>? ~'c) }) (quote ~func))
~'rep
(~'<! ~'c))))
Result: This fails since rep
is just ends up being a literal, unevaluated list. If I were able to type (eval rep)
on the second to last line instead of just rep
, my problem would be fixed, but I cannot since I'm working in ClojureScript (where there is no eval). How do I get around this?
.readFile
method, so(.readFile "/path/to/file")
can never be correct. There's no reason at all to(let [rep (foo)] rep x)
, instead of just writing(do (foo) x)
. You probably just want to write~(replace ...)
instead of(replace ...)
, but it's hard to be sure since your desired input and outpot don't entirely make sense. – amalloy