Reputation: 1231
I've been working to figure out a was to evaluate collections of forms with arguments.
An example function:
(defn x
[a b c]
(+ a b c))
I would like to evaluate collections of the function x, where only some parameters are defined and others are passed in to end up with a list of the products of the evaluations of the x functions in the collection:
(defn y
[z]
(map #(eval %) [(x z 1 1) (x z 2 2) (x z 8 64)]))
The question is: how do I introduce z as a parameter to each of the functions in the collection when I map eval to each? Is this possible?
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
Is there a better way to accomplish this?
Thanks!
Upvotes: 1
Views: 67
Reputation: 16194
First, let's use some more explanatory names, simplify the definition of x
, and not use eval
:
(defn sum [& xs]
(apply + xs)) ;; could be inlined instead of a function
(defn sum-with [z]
(map (partial apply sum)
[[z 1 1]
[z 2 2]
[z 8 64]]))
(sum-with 3)
=> (5 7 75)
But I assume your real world problem is something more complex than summing numbers, so I'll assume your x
function is doing something else and requires some positional arguments i.e. the order of arguments matters:
(defn transmogrify [this n1 n2 that]
(+ n1 n2 (* this that)))
(defn evaluate-sums [a b]
(map (partial apply transmogrify)
[[a 1 1 b]
[a 2 2 b]
[a 8 64 b]]))
(evaluate-sums 3 9)
=> (29 31 99)
So if I understand correctly, you can accomplish your goal just by apply
ing sequences of arguments to your function. Or to be more explicit with args/not use apply
, just use a more specific anonymous function with map
:
(defn evaluate-sums [z]
(map (fn [[this n1 n2 that]]
(transmogrify this n1 n2 that))
[[z 1 1 99]
[z 2 2 360]
[z 8 64 -1]]))
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
If your "fixed" arguments are always the same arity, then you can use variadic arity for the rest of the arguments:
(defn sum [a b & cs]
(apply + a b cs))
(defn evaluate-sums [zs]
(map (fn [[a b & cs]]
(apply sum a b cs))
[[1 1 zs]
[2 2 zs]
[8 64 zs]]))
Where zs
is a collection/sequence of your extra arguments.
Upvotes: 3