2009-03-24 8 views
15

Je voudrais le faire (en REPL ou partout)Comment défnir une fonction d'une chaîne dans Clojure?

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

et être en mesure de faire

(print-string "lol") 

Ou, s'il y a une autre façon de créer defn de chaînes personnalisées en macroses, pourriez-vous me pousser dans la bonne direction s'il vous plaît?

Répondre

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

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

(print-string "lol") 
+0

1. Quelle est la ~ devant args? 2. quel est le ~ @ devant le corps? – Belun

+1

@Belun 1. ~ = unquote 2. ~ @ = expansion de la séquence – Surya

+0

pourquoi est-ce que si je le fais (defn defns [] (doall (map (fn [s] (defn-avec-str s [k] (println k))) ["print-string"]))) J'ai un fn appelé 's'? – Hendekagon

14

J'aime la réponse de dnolen mieux, mais vous pouvez le faire aussi:

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

#=() est évaluée à lecture du temps. Je ne sais pas à quel point c'est une caractéristique stable de Clojure, je ne me fierais pas à cela pour ne pas changer à l'avenir. Les macros sont comme ça que je ferais.

17

La solution de dnolen fonctionne au temps de la macro-expansion, celle de Brian Carper au moment de la lecture. Maintenant, voici un pour l'exécution:

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

Cool ne le savait pas. Une mise en garde est que la var a manquera les métadonnées de la fonction que vous obtenez en utilisant defn. – dnolen

7

Pour votre information - La réponse de dnolen ne fonctionnera que pour les chaînes littérales, et non pour les chaînes en def'd ou des variables let'd.

(defmacro defn-with-str [chaîne args & corps] `(defn ~ (chaîne de symboles) ~ args ~ @ corps))

(hisym def "salut") (defn-avec- str hisym [] (println "salut"))

Vous avez maintenant une fonction appelée "hisym"

(salut) -> java.lang.Exception: Impossible de résoudre le symbole: salut dans ce contexte (NO_SOURCE_FILE : 6) (hisym) -> impressions "salut"

Pour éviter cela, eval la chaîne de nom de fonction dans la macro

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

Questions connexes