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

Gab*_*iMe 7 functional-programming clojure

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

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

(defn gen-fn [name arg-symbols body]
...
...
Run Code Online (Sandbox Code Playgroud)

将使用这样:

(gen-fn "my-func-name" (symbol "x") (symbol "y") (println "this is body. x=" x))
Run Code Online (Sandbox Code Playgroud)

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

kot*_*rak 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)))
Run Code Online (Sandbox Code Playgroud)

还有一些用途:

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

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

  • 不,宏在编译时运行,而不是在运行时运行. (3认同)
  • 很好的答案.我只想补充一点,如果遗传编程的目的那么将生成的函数直接存储在地图中而不是将它们添加到命名空间中可能是有意义的(这可能会让人感到困惑,因为它是一大块可变状态...) (3认同)