On 22.05.2009, at 10:03, Mark Engelberg wrote: > However, there seems to be one way that this solution falls short of > the load-and-redefine technique.
I don't think it can ever fall short of the load-and-redefine technique because you can emulate it completely (unless I overlooked something): you set up a template without any parameters. In that case, it will be introduced verbatim into the namespace where the template is used, and then you can redefine whatever you want. You still gain something compared to load-and-redefine: the template is an ordinary Clojure object residing in a namespace, so it works without any namespace trickeries and a template can even be used if its defining namespace has been aot-compiled and the original source code is not available. Of course, I'd like to do even better than that and make parametrization of the template as clean as possible, so your counterexample is still relevant. > Imagine if, in the example above, the function that you want to set > up for extension is > print-grav-stats. I don't think that will work with your method > because print-grav-stats refers to variables that would not be in > scope when the macro expands. As long as it uses the same variables as the template, it would still work, but (like the load-and-redefine method) it would fail as soon as the template author decides to change the names of his variables. I suppose that to some extent such a risk is inevitable with any method based on textual replacement. C macros are famous for that kind of problem, and my templates work at pretty much the same level as C macros. A well-defined template should define anything meant to be changed as template parameters, clearly state the symbols that the template itself inserts into the namespace, and use gensyms for anything else. My current version doesn't permit to define gensyms, but I think that could be added easily. Of course, writing such a well-behaved template represents more effort than wrapping a piece of code in a (deftemplate ...) form. > If there were a way to declare all the > variables in the body of the macro BEFORE the let, and then the > definitions, I think that might fix it, but I'm not totally sure how > to do that. What do you call "variables" here? All the symbols that are used inside the template expansion? > If you don't have side effects in forms, you can simply execute the > forms before the let, thus ensuring all vars are in scope. I think > just changing expansion to: > (list (list 'quote (cons 'do forms)) > (list 'list (list 'quote `symbol-macrolet) param-map > (list 'quote (cons 'do forms)))) > would do the trick. I'd expect that executing before the let would lead to lots of "undefined symbol" errors. Konrad. --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---