On 2 Apr 2005 08:39:35 -0800, "Kay Schluehr" <[EMAIL PROTECTED]> wrote:
> >There is actually nothing mysterious about decorators. I've heard this quite a few times now, but *is* quite mysterious if you are not already familiar with how they work. Or instead of mysterious, you could say complex, as they can be used in quite complex ways. What is missing most with them is some really good documentation. I got the basic idea and syntax of decorators down right away, but ran into problems implementing them because, the structure of the functions being used for the decorators wasn't clear. >It is nothing >more than ordinary function composition, executed when the decorated >function is defined. In case of Your definition it, the composition >rules are: > >decorator("Goodbye")(func)(s) = get_function(func)(s) = wrapper(s), >where wrapper stores "Goodbye" in the local d_arg. It worked as a model, but I mixed in concepts from cstacks and function calls, which apparently isn't correct. I posted another model, it should be a bit closer. (with the Subject line spelled correctly, continue this thread there. ;) >Or a bit more formally we state the composition principle: > >Args x Func -> Func, where decorator() is a function of Args, that >returns a function Func -> Func. As Guido had shown recently in his >Artima blog, Func need not be an instance of an ordinary function but >can be a function-object like his MultiMethod : > >http://www.artima.com/weblogs/viewpost.jsp?thread=101605 I read this, this morning it was very interesting. >It is also possible to extend this view by "chaining" decorators. > >decorator : Args(2) x (Args(1) x Func - > Func ) -> Func. > >To understand decorator chains it is very helpfull to accept the >functional view instead of arguing in a procedural picture i.e. pushing >and popping arguments onto and from the stack. Understanding chains is next on my list. :) >Someone asked once for a solution of the following problem that is >similar in character to Guidos multimethod but some more general. > >def mul(m1,m2): > def default(m1,m2): > return "default",1+m1*m2 > def mul_dec(m1,m2): > return "mul_dec",Decimal(str(m1))*Decimal(str(m2)) > def mul_float(m1,m2): > return "mul_float",m1*m2 > return (default,mul_dec,mul_float) > >The function mul defines the inner functions default, mul_float and >mul_dec. What we want is a unified access to this functions by means of >mul. Guidos solution would decompose mul in three different versions of >mul: This is similar to c++'s polymorphism which I've played with nearly 10 years ago. I generally found it useful only in small doses even then. I seem to think now that c++'s version of it was implemented at compile time, with each function call being matched up with the correct function, by the argument types. Where as Guido's version, is dynamic and handles the situation at run time. I may not be correct in this, it's been a while. >@multimethod(int,float) >def mul(m1,m2): > return m1*m2 > >@multimethod(float,float) >def mul(m1,m2): > return m1*m2 > > >@multimethod(Decimal,Decimal) >def mul(m1,m2): > return m1*m2 > >but it is hard to tell, what should be done if no argument tuple >matches. It could then invoke the adapt() function to determine if a possible single way to continue is available. But with that you could run into some very subtle bugs. Or just annoying windows like behavior, such as a word processor auto correcting a word when don't want it to. >An attempt like: > >@multimethod(object,object) >def mul(m1,m2): > return 1+m1*m2 > >would be useless, because there is no concrete match of argument types >onto (object,object). > >So I introduced an "external switch" over argument tuples, using a >decorator chain: > >@case(None,"default") >@case((float,float),'mul_float') >@case((int,float),'mul_float') >@case((Decimal,Decimal),'mul_dec') > >def mul(m1,m2): > def default(m1,m2): > return "default",1+m1*m2 > def mul_dec(m1,m2): > return "mul_dec",Decimal(str(m1))*Decimal(str(m2)) > def mul_float(m1,m2): > return "mul_float",m1*m2 > return (default,mul_dec,mul_float) > >Can You imagine how "case" works internally? > >Regards, >Kay Sure, That should be fairly straight forward. Although I can imagine several ways of implementing it at the moment. I think after I play with decorator chains, one way will probably stand out as being cleaner than the others. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list