On Fri, Jun 3, 2011 at 10:36 AM, nil <ache...@gmail.com> wrote: >> The problem here is that macros run at compile time, but let bindings >> exist at run time. >> >> If you need the name to be determined at run time you will need to use eval. > > Where do I use eval? I tried looking at the argument to see if it was > called with a string literal vs a symbol, but can't eval a local: > > (defmacro foo [x] > (let [name-as-string# (if (symbol? x) (eval x) x) > name-as-symbol# (symbol name-as-string#)] > `(defn ~name-as-symbol# [] ()))) > > (let [eff "gee"] (foo eff))
You'd need to use eval *instead* of defmacro in that case: => (let [eff "gee"] (eval `(defn ~(symbol (str "foo-" eff)) [] (println "Hello, world!")))) #'user/foo-gee => (foo-gee) Hello, world! nil => But there's probably a *much* better way to do whatever you're trying to do that doesn't involve using eval. >> If you don't need the name at run time, why are you using (let [eff >> "gee"] (foo eff)) and not simply (foo gee)? > > I'm using let because I'd like to have the name at run time. I'm > defining families of functions to manipulate types of UI elements by > saying (type page-name field-name locator). Without knowing a solution > to my problem, I'm stuck saying the following in order to generate a > bunch of functions to use later in my program... > > (txt "registration" "username" "id=Username") > (txt "registration" "password" "id=Password") > (tog "registration" "terms" "id=AcceptTerms") > (nav "registration" "submit" "//html/body/div/form/div/input" "/ > SignedIn") > > ... Instead of this: > > (let [page "registration"] > (txt page "username" "id=Username") > (txt page "password" "id=Password") > (tog page "terms" "id=AcceptTerms") > (nav page "submit" "//html/body/div/form/div/input" "/SignedIn")) That should work if txt, tog, and nav are normal functions, and could work if they're macros depending on how they're written, but I take it they're macros and it doesn't work. How about: (doto "registration" (txt "username" "id=Username") (txt "password" "id=Password") (tog "terms" "id=AcceptTerms") (nav "submit" "//html/body/div/form/div/input" "/SignedIn")) It's not exactly what the doto macro was intended for, but it *should* work. -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en