1

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...

Zara Kay
  • 164
  • 1
  • 8

1 Answers1

1

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.

erdos
  • 3,135
  • 2
  • 16
  • 27