So I am working on a stream function which will sum up some metrics for several events. To do this I use the project
function and it looks something like this:
(project [(func (:service event) (nth service-list 0))
(func (:service event) (nth service-list 1))
(func (:service event) (nth service-list 2))]
(..))
service-list
is a argument of the surrounding function, which contain a vector of services that must be added together. func
is a function that takes two arguments and returns a true
/false
Using the above snippet works fine, but I would like to be able to simplify it so that a vector that is larger or smaller than 3 elements would work.
So far I have this:
(project (mapv (fn[service] (
`func (:service event) ~service)
) service-list)))
(..)
which I think returns a vector of functions which are unevaluated. I went with this approach once I realised that project
is a macro. No idea if I am doing the right thing...
The problem you are facing is that you can not dynamically assemble just the arguments of a macro call. Therefore you need to dynamically assemble the whole macro call.
You can build a clojure form and call eval on it. Take the following.
(let [args (mapv #(list 'func (:service 'event) %) service-list)
form (list 'project args (...))]
(eval form))
Or, you could also use the riemann.streams/project* function to use predicate functions instead of where expressions.