Clojure:如何在运行时创建函数

时间:2009-12-01 09:09:39

标签: functional-programming clojure

我想在运行时完全生成一个fn(即名称和arg符号在运行时决定,而不是在代码中决定) 实现这一目标的最佳方法是什么?

例如,我如何实现以下功能?

(defn gen-fn [name arg-symbols body]
...
...

将像这样使用:

(gen-fn "my-func-name" (symbol "x") (symbol "y") (println "this is body. x=" x))

请注意,函数名称,args和body未编码,但可以在运行时决定

3 个答案:

答案 0 :(得分:12)

(defn gen-fn
  [n as b]
  (let [n        (symbol n)
        as       (vec (map symbol as))
        fn-value (eval `(fn ~n ~as ~b))]
    (intern *ns* n fn-value)))

有些人使用:

user=> (gen-fn "foo" ["x"] '(do (println x) (println (inc x))))
#'user/foo
user=> (foo 5)
5
6
nil

但是,我并不喜欢这种方法。它闻起来很难闻:eval。为什么要在运行时生成全局变量?我看到错误的命名空间和其他丑陋的打嗝出现在各种问题......

答案 1 :(得分:1)

另一种方法是使用“eval”和“read-string”:

用户=> (def f1(eval(read-string“(fn [x y](* x y))”)))

#'用户/ F1

用户=> (f1 3 5)

15

答案 2 :(得分:0)

我不完全确定,但我相信你可以使用一个优于eval的宏来做到这一点。

(defmacro gen-fn
  [n as b]
  (let [n  (symbol n)
        as (vec (map symbol as))]
    `(intern *ns* n (fn ~n ~as ~@b))))