> It's not clear in the case of multiple packages or namespaces. (In which > package does "name" get interned? It depends on *when* the string is > interned, because that decides the enclosing scope. Or does newLISP not have > packages?)
NAME (not name) may be "interned" in the sense that it will exist somewhere in the symbol tree, but that doesn't matter—at all. At least in newLISP. In Clojure it may have some consequences and if so, that would be a valid argument to make, I'd be interested to know what they are if that is the case. > Neither are the names specified in a query such as "SELECT * FROM people". > Who knows what'll happen when you do "SELECT p1.name ...". This is incorrect. A query like "SELECT *" will not have any issues getting the correct, expected names from the table definition. You can check the code again, there's no string parsing going on with the query. > - Quietly and maybe accidentally shadows variables from enclosing scopes If any shadowing happens, it's OK because you know it's going to happen. It's also exceedingly unlikely it will happen due to naming convention and even if it happens, it's *still OK* because nothing breaks because things are only shadowed within the scope of the macro call and you're explicitly expecting to use the NAME symbol, etc. There's zero confusion and zero ambiguity. > - Uses eval (which apparently is fine in newLISP, but as a Common Lisper and > Clojurite strikes me as pointless) So, as I showed, the Clojure version seems to not require the use of eval. > c.c.sql also allows you to synthesize queries from Lisp forms This is a good point, and if I were to use Clojure I would use your version instead. - Greg On Feb 4, 2010, at 5:53 PM, Richard Newman wrote: >> OK, I hope you can see the difference though between that and what I showed. > > Of course I can; I'm just illustrating a point by exaggeration. > >> 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) > > It's not clear in the case of multiple packages or namespaces. (In which > package does "name" get interned? It depends on *when* the string is > interned, because that decides the enclosing scope. Or does newLISP not have > packages?) > > Neither are the names specified in a query such as "SELECT * FROM people". > Who knows what'll happen when you do "SELECT p1.name ...". > > You're about half-way to complete anaphora when you're starting to pull > symbol names out of syntax-laden strings (or databases). That's magic, at > least when compared to ordinary lexical symbol reference. > > Given that there's little to no advantage to doing this, I don't see the > point. > >> 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 > > ... and it's a bad example, because it: > > - Quietly and maybe accidentally shadows variables from enclosing scopes > - Fails to nest queries which share names > - Silently interns new variable names in your packages > - Uses eval (which apparently is fine in newLISP, but as a Common Lisper and > Clojurite strikes me as pointless) > - etc. > > I see no point in doing this rather than going the conventional macro route. > c.c.sql, for example, would do this: > > (with-query-results res > ["SELECT name FROM people"] > (println (:name res))) > > -- res is a map. You can pass it around, access its values, and your own > function `name` doesn't get shadowed by your query. > > c.c.sql also allows you to synthesize queries from Lisp forms, which I think > is more useful than trying to extract symbol names from a SQL string. > >>> 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! > > Sure thing! > > -- > 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