Function 如何从函数列表和值构造函数?

Function 如何从函数列表和值构造函数?,function,macros,clojure,Function,Macros,Clojure,我试图用一个已经计算过的函数和一系列其他函数的结果来构建一个函数。如果我部分构建它,它工作得很好,但每次我尝试构建整个东西时,它都失败了 (defn play [] (let [eval1 (eval '(+ 1 1))] (eval `(->> ~eval1 (+ 5) (- 2) (* 7))) ) ) 这失败了: (defn play [] (let [eval1 (eval '(+ 1 1)) eval2 '((

我试图用一个已经计算过的函数和一系列其他函数的结果来构建一个函数。如果我部分构建它,它工作得很好,但每次我尝试构建整个东西时,它都失败了

(defn play [] 
    (let [eval1 (eval '(+ 1 1))]
        (eval `(->> ~eval1 (+ 5) (- 2) (* 7)))
    )
)
这失败了:

(defn play []
    (let [eval1 (eval '(+ 1 1))
          eval2 '((+ 5) (- 2) (* 7))]
        (eval (cons (cons eval1 eval2) ->>))
     )
)
我已经尝试了很多其他的方法来把这些结合在一起,我认为这归结为我不太理解clojure的这一方面。解决这个问题最好的办法是什么?谢谢

。然而,也许这一次你会这样做,无论出于什么原因(理解Clojure的读者是一个合理的理由)。所以答案取决于你所说的“这个问题”是什么意思

第1部分-带eval

韦伯的很好。如果您给出的示例只是为了让您了解Clojure reader的工作原理,那么我的其余答案可能与您无关

第二部分——无需评估

如果“此问题”是指从函数列表和值构造函数,则不需要
eval
。将
(eval'(+1))
替换为
(+1)
。然后,因为您需要一个函数列表,所以可以使用etc.或etc.并将其存储在列表中

是一个线程宏。这意味着它在编译时执行,以转换其整个S表达式。但在失败的代码中,它在编译时没有S表达式——您可能试图在运行时通过
cons
将其添加到另一个列表中来构建它的S表达式

您可以在这里编写另一个宏来执行您想要的操作。但一般来说,当我遇到将函数列表应用于初始值的问题时,我使用:

事实上,这在我的代码中经常出现,因此我的大多数项目的核心都有这一点。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))
最后,如果要构造函数而不是其求值,请使用以下内容包装返回值:


你的第二个
游戏有两个问题:(1)你没有引用
->
,因此Clojure会抱怨“获取宏的值”,你想做符号操作;和(2)您将列表按错误的顺序排列在一起

试一试

其他要考虑的事情是使用普通函数或宏,使用语法引用来捕获命名空间,使用<代码>列表*>代码>而不是两个<代码> CONS .< /P> <代码>(+ 1 1)< /> >不是一个函数,<代码>((+ 5)(-2)(*7))< /C>不是函数列表。

如果你有一个函数列表,比如

(def fns (list (partial + 5) (fn [x] (- 2 x)) #(* 7 %)))
您可以实现“从函数列表构造函数”的目标

然后您可以使用“一个已计算函数的结果[call]”调用它:


->>是一个宏。不能将宏的值带入eval函数,因为宏只存在于编译时上下文中。第一位可能是上下文之外的误导。通常,您将使用符号进行编译时操作。幸运的是,在其他宏的主体中解析宏的符号工作得很好。谢谢,你答案的第二部分准确地描述了我想要解决的问题。
(defn play []
    (let [in (+ 1 1)
          fs (list #(+ 5 %) #(- 2 %) #(* 7 %))]
        (fn [] (freduce in fs))))

user=> ((play))
-35
(defn play []
  (let [eval1 (eval '(+ 1 1))
        eval2 '((+ 5) (- 2) (* 7))]
    (eval (cons '->> (cons eval1 eval2)))))
(def fns (list (partial + 5) (fn [x] (- 2 x)) #(* 7 %)))
(def master-fn (->> fns reverse (apply comp)))
(master-fn (+ 1 1))
;; => -35