I want to generate a fn totally at runtime (i.e. the name and the arg symbols are decided at runtime, not in code) What's the best way to achieve this ?
For example how can I implement the following function ?
(defn gen-fn [name arg-symbols body]
...
...
which would be used like this:
(gen-fn "my-func-name" (symbol "x") (symbol "y") (println "this is body. x=" x))
Note that function name, the args and the body are not coded but can be decided at runtime
(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)))
And some use:
user=> (gen-fn "foo" ["x"] '(do (println x) (println (inc x))))
#'user/foo
user=> (foo 5)
5
6
nil
However, I don't really like this approach. It smells really hard: eval
. Why do you want to generate globals at runtime? I see various problems with wrong namespaces and other ugly hiccups rising at the horizon...
Another way is using "eval" and "read-string":
user=> (def f1 (eval (read-string "(fn [x y] (* x y))")))
#'user/f1
user=> (f1 3 5)
15
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With