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
-~----------~----~----~----~------~----~------~--~---

Reply via email to