I'm trying to implement a (very) simple actor model prototype in clojure. Each actor would have, as the loop to handle the arrival of messages, a go-loop
. I wanted to invoke, inside this go-loop
, functions that would either take from or put into a channel. I really wanted parking behaviour on these inner channel operations, but I can't actually use <!
or >!
to do it so, because the operations wouldn't be directly inside the go-loop
. Can I use macros to circumvent such limitation? If so, how would I do it?
To illustrate the issue simply, in the following snippet, how can I change foo
so that the code actually compiles and I get parking behaviour?
(defn main-loop
[ch]
(async/go-loop [] (foo ch) (recur)))
(defn foo [ch] (>! ch "Hello, World!"))
You can use macros to write any code that you could write by hand, and that's all. So if you just want your functions to be convenient shorthand for using >!
inline, then sure, you can replace the functions with macros. If you want to do something fancier, like map that function over a list of messages, then you can't, because that would involve bundling them up in a function to pass to map
.
A simple example would just be
(defmacro foo [ch]
`(>! ~ch "Hello, World!"))
Whether this is the solution to your problem, or something else is (such as using >!!
), depends on what you want to be able to do with these things.