On Feb 4, 2010, at 1:51 PM, Richard Newman wrote: >>> * You don't have to fiddle with magic names. The user can choose himself. >> >> These aren't magic names, they're just like you keywords, except they're >> symbols, and they're not magic because they're defined by the columns of the >> table. Or, I may be misunderstanding your use of the term 'magic'. > > They're magic because they're not introduced via normal lexical scoping. Not > magic: > > (let [x 5] > (do-something (foo x))) > > Magic: > > (with-implicit-wizard > (do-something (foo gandalf)))
OK, I hope you can see the difference though between that and what I showed. They are not the same; in your example: - It's not clear what the magic symbols are - The user does not specify the magic symbols (as they did in mine) This sort of programming style is easy to abuse and can sometimes lead to confusion if handled incorrectly, but when applied in the appropriate manner it can be extremely useful. The 'for-query-with-db' function is a good example of doing this correctly because it: - Documents its behavior - Creates symbols based on user input, not of its own accord as in your example - Clearly distinguishes them through a special naming convention - Has advantages over other forms of solving the same problem >> That seems to work great, what I'm fuzzy on is the whole macroexpansion >> thing and when it occurs. As in this example everything is known at >> compile-time, is this "macro-expanded" at compile time? Can this sort of >> macro work just fine when the column information is only known at runtime? >> Are there any performance considerations? > > The macroexpansion occurs at compile time. If you have all the knowledge at > compile time, you can do the work then. If you don't, the macro has to expand > into code that does the work at runtime. Thanks for the example and explanation! - Greg > For example, to write a macro that prints upper-cased strings, you might do > this: > > (defmacro all-upcase [& args] > `(println ~@(map (fn [x] (if (string? x) (.toUpperCase x) `(.toUpperCase > ~x))) args))) > > ... it does the upcasing at compile-time for static strings, and at runtime > for everything else. You can see what happens by using macroexpand: > > user=> (macroexpand '(all-upcase "foo" "bar" x y)) > (clojure.core/println "FOO" "BAR" (.toUpperCase x) (.toUpperCase y)) > > user=> (let [x "hi" y "there"] (all-upcase "foo" "bar" x y)) > FOO BAR HI THERE > > -- > 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 -- 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