You generally don't want to use eval
. However, maybe this time you do, for whatever reason (understanding Clojure's reader is a valid reason). So the answer depends on what you mean by "this problem."
Part 1 -- with eval
A. Webb's answer is perfectly fine. If the example you gave is just so you can learn how the Clojure reader works, the rest of my answer may be irrelevant to you.
Part 2 -- without eval
If by "this problem" you mean constructing a function from a list of functions and a value, you don't want eval
. Replace (eval '(+ 1 1))
with (+ 1 1)
. Then because you want a list of functions, you can use #(+ 5 %)
etc. or (partial + 5)
etc. and store those in a list.
->>
is a threading macro. This means it is executed at compile time, to transform its whole S-expression. But in your failed code, it doesn't have an S-expression at compile time -- you would be attempting to craft its S-expression at run time by cons
ing it onto another list.
You could write another macro to do what you want here. But in general, when I confront the problem of applying a list of functions to an initial value, I use reduce:
(defn play []
(let [eval1 (+ 1 1)
eval2 (list #(+ 5 %) #(- 2 %) #(* 7 %))]
(reduce #(%2 %) eval1 eval2)))
In fact, this comes up often enough in my code that most of my projects have this in their core.clj:
(defn freduce
"Given an initial input and a collection of functions (f1,..,fn),
This is logically equivalent to ((comp fn ... f1) input)."
[in fs]
(reduce #(%2 %) in fs))
Finally, if you want to construct a function rather than its evaluation, then wrap the return value with fn
:
(defn play []
(let [in (+ 1 1)
fs (list #(+ 5 %) #(- 2 %) #(* 7 %))]
(fn [] (freduce in fs))))
user=> ((play))
-35