Question

I'd like to do this (in REPL or anywhere)

(defn (symbol "print-string") [k] (println k))

and then be able to do

(print-string "lol")

Or, if there is any other way to create defn from custom strings in macroses, could you push me into the right direction please?

Was it helpful?

Solution

(defmacro defn-with-str [string args & body]
 `(defn ~(symbol string) ~args ~@body))

(defn-with-str "print-string" [k] (println k))

(print-string "lol")

OTHER TIPS

dnolen's solution works at macro expansion time, Brian Carper's at read-time. Now, here's one for run-time:

(intern *ns* (symbol "a") (fn [k] (println k)))

I like dnolen's answer better, but you can do this too:

(defn #=(symbol "print-string") [k] (println k))

#=() is evaluated at read-time. I don't know how stable a feature of Clojure this is, I wouldn't rely on it not to change in the future. Macros are how I'd do it.

FYI - dnolen's answer will only work for literal strings, and not for strings in def'd or let'd variables.

(defmacro defn-with-str [string args & body] `(defn ~(symbol string) ~args ~@body))

(def hisym "hi") (defn-with-str hisym [] (println "hi"))

You now have a function called "hisym"

(hi) -> java.lang.Exception: Unable to resolve symbol: hi in this context (NO_SOURCE_FILE:6) (hisym) -> prints "hi"

To avoid this, eval the function name string in the macro

(defmacro defn-with-str [string args & body]
`(defn ~(symbol (eval string)) ~args ~@body))

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top