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?
.readFilemethod, 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