Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to evaluate sequence of pure functions in Clojure

Tags:

clojure

lisp

My question is pretty similar to this one: How to evaluate a sequence of impure functions in Clojure? but instead of impure functions, how can I evaluate sequence of pure functions and get the results as another sequence?

Let's assume we have a vector of functions like:

[#(str "a" "b") #(str "c" "d") #(str "e" "f")]

And we need an output like this:

("ab" "cd" "ef")

I've tried something similar to this:

(map eval [#(str "a" "b") #(str "c" "d") #(str "e" "f")])

but it just returns a vector of function references.

like image 351
slhsen Avatar asked Dec 04 '25 18:12

slhsen


1 Answers

There are multiple ways to do what you are asking. It depends on whether you want a lazy sequence or not (you probably want lazy given there are no side-effects, but you might want no-lazy if there's an intensive computation that you want to cache), or if you want a vector as output (the same as your input). I'll try to follow what you tried to do.

Your map with eval is doing the following with each fn:

user=> (eval #(str 1))
#<user$eval1332$fn__1333 user$eval1332$fn__1333@38747597>

But you want something like the following:

user=> (eval (#(str 1)))
"1"

You want eval to have the fn applied, that is: the fn should be the first element of a list. Let's put it in a list:

user=> (map (comp eval list) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")

Cool. But instead of eval, you probably want to use apply:

user=> (apply #(str 1))
; ArityException Wrong number of args (1)

Ups! It failed. apply doesn't have a 0-arity overload, but we can pass an empty list:

user=> (apply #(str 1) ())
"1"

Much better. Let's do it with map:

user=> (map #(apply % ()) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")

Or better yet, given your functions receive no arguments, you'd better do as suggested by @Magos:

user=> (map #(%) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])                                                                              
("ab" "cd" "ef")
like image 95
nberger Avatar answered Dec 06 '25 12:12

nberger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!