[Python-Dev] defmacro (was: Anonymous blocks)

Samuele Pedroni pedronis at strakt.com
Tue Apr 26 00:45:43 CEST 2005


Robert Brewer wrote:
> Shane Hathaway wrote:
> 
>>Robert Brewer wrote:
>>
>>>So currently, all subclasses just override __set__, which leads to a
>>>*lot* of duplication of code. If I could write the base 
>>
>>class' __set__
>>
>>>to call "macros" like this:
>>>
>>>    def __set__(self, unit, value):
>>>        self.begin()
>>>        if self.coerce:
>>>            value = self.coerce(unit, value)
>>>        oldvalue = unit._properties[self.key]
>>>        if oldvalue != value:
>>>            self.pre()
>>>            unit._properties[self.key] = value
>>>            self.post()
>>>        self.end()
>>>
>>>    defmacro begin:
>>>        pass
>>>    
>>>    defmacro pre:
>>>        pass
>>>    
>>>    defmacro post:
>>>        pass
>>>    
>>>    defmacro end:
>>>        pass
>>
>>Here is a way to write that using anonymous blocks:
>>
>>    def __set__(self, unit, value):
>>        with self.setting(unit, value):
>>            if self.coerce:
>>                value = self.coerce(unit, value)
>>            oldvalue = unit._properties[self.key]
>>            if oldvalue != value:
>>                with self.changing(oldvalue, value):
>>                    unit._properties[self.key] = value
>>
>>    def setting(self, unit, value):
>>	# begin code goes here
>>        yield None
>>        # end code goes here
>>
>>    def changing(self, oldvalue, newvalue):
>>        # pre code goes here
>>        yield None
>>        # post code goes here
>>
> 
> ...
> 
>>Which do you prefer?  I like fewer methods. ;-)
> 
> 
> I still prefer more methods, because my actual use-cases are more
> complicated. Your solution would work for the specific case I gave, but
> try factoring in:
> 
> * A subclass which needs to share locals between begin and post, instead
> of pre and post.
> 
> or
> 
> * A set of 10 subclasses which need the same begin() but different end()
> code.
> 
> Yielding seems both too restrictive and too inside-out to be readable,
> IMO.
> 
> 

it seems what you are asking for are functions that are evaluated in 
namespace of the caller:

- this seems fragile, the only safe wat to implement 'begin' etc is to 
exactly know what goes on in __set__ and what names are used there

- if you throw in deferred evaluation for exprs or suites passed in
as arguments and even without considering that, it seems pretty horrid 
implementation-wise

Notice that even in Common Lisp you cannot really do this, you could 
define a macro that produce a definition for __set__ and takes fragments 
corresponding to begin ... etc






More information about the Python-Dev mailing list