> I don't see why a macro should be of more use here. With a macro the db query > is always done, when the page is compiled. I don't see how this would an > advantage. With a function it could be compiled once at startup and when the > page is accessed you just fire off a clojure function which does the work. > enlive works like that, AFAIK. You would have to "recompile" the page only > when its source is changed.
Perhaps this isn't the right approach to take in Clojure because of the slow eval. I'm not sure exactly if this can be done without it. If it can though it should be as fast as Enlive or faster. You "compile" the template once to Clojure source, and then re-run that source each time the page is called. Enlive has to reconstruct HTML from its data structures. This, on the other hand, mostly just prints already "rendered" strings, and calls any clojure functions/macros along the way. Again, though, if that's not possible to do in Clojure without using eval (as I do in newLISP), then I would see why Enlive's approach is preferred. > eval is in general discouraged, not because it's slow, but because its bad > style. For example clojure's eval wouldn't help you with let. > > user=> (let [x 5] (eval 'x)) > java.lang.Exception: Unable to resolve symbol: x in this context > (NO_SOURCE_FILE:1) > user=> (let [x 5] (eval `x)) > java.lang.Exception: No such var: user/x (NO_SOURCE_FILE:2) In newLISP it's not discouraged because it's not bad style. This works no problem: > (let (x 5) (eval 'x)) 5 Even if Clojure could do this, I would still agree with you that eval's use should be discouraged, but only because of how slow it is: user=> (dotimes [_ 4] (time (dotimes [_ 1000] (eval '(+ 1 1)))))) "Elapsed time: 1797.558 msecs" "Elapsed time: 1590.405 msecs" "Elapsed time: 1274.187 msecs" "Elapsed time: 1808.667 msecs" vs. > (time (dotimes (_ 1000) (eval '(+ 1 1)))) 0.3 Yes, that's in milliseconds. > What happens in newLisp if you have a macro which does some eval on an > argument and the user passes it a function call which asks the user for input > from a console? That's silly, what happens when you pass in a string to a function that's expecting a double? That's what documentation is for. And if you want the macro/fexpr to accept function as well as symbols, you can always rewrite it to check for both and act appropriately. - Greg On Feb 4, 2010, at 2:16 PM, Meikel Brandmeyer wrote: > Hi, > > Am 04.02.2010 um 18:55 schrieb Greg: > >> I need it to be a macro because it's more usable for my purposes that way. >> The newLISP function is being used to generate templates php-style: >> >> <table> >> <tr><td>Name</td><td>Email</td></tr> >> <% (for-query-with-db db "SELECT * FROM people" %> >> <tr><td><%=NAME%></td><td><%=EMAIL%></td></tr> >> <% ) %> >> </table> >> >> As you can see it's much more convenient as a macro. > > I don't see why a macro should be of more use here. With a macro the db query > is always done, when the page is compiled. I don't see how this would an > advantage. With a function it could be compiled once at startup and when the > page is accessed you just fire off a clojure function which does the work. > enlive works like that, AFAIK. You would have to "recompile" the page only > when its source is changed. > >>> * 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'. > > Richard explained what I meant. > >>> * The query can be also stored in some local and doesn't have to be a >>> literal string. >> >> >> There's nothing forcing you to use it as a literal, the newLISP version can >> be used with a let statement just as your example did. > > eval is in general discouraged, not because it's slow, but because its bad > style. For example clojure's eval wouldn't help you with let. > > user=> (let [x 5] (eval 'x)) > java.lang.Exception: Unable to resolve symbol: x in this context > (NO_SOURCE_FILE:1) > user=> (let [x 5] (eval `x)) > java.lang.Exception: No such var: user/x (NO_SOURCE_FILE:2) > > What happens in newLisp if you have a macro which does some eval on an > argument and the user passes it a function call which asks the user for input > from a console? > > Sincerely > Meikel > > -- > 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