15

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?

4 Answers 4

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

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

(print-string "lol")
Sign up to request clarification or add additional context in comments.

4 Comments

1. what is the ~ in front of args ? 2. what is the ~@ in front of body ?
@Belun 1. ~ = unquote 2.~@ = expand sequence
why is it that if I do (defn defns [] (doall (map (fn [s] (defn-with-str s [k] (println k))) ["print-string"]))) I get a fn called 's' ?
@Hendekagon macros aren't regular functions
17

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)))

1 Comment

Cool did not know about that. One caveat is that the var a will be missing the function metadata that you get from using defn.
14

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.

Comments

7

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.