[NAME] ALL.misc.comparison.decorator [TITLE] Function Decorator (Python) [DESCRIPTION] Decorators are a special type of functions that can be used to enhance the functionaliti es of other functions by decorating them. 0.1 Decorators for Single Functions In Python, a decorator is just a callable that can take a function as an input argument and return a replacement function as output. For example, 1 def Decorator( func ): 2 def newfunc(): 3 ret = func() 4 return ret + 123 5 return newfunc 6 7 def Foo(): 8 return 456 9 10 deco = Decorator( Foo ) 11 deco() Dao decorators are quite different from Python decorators. Dao decorators do not return r eplacement functions, instead, they are defined as the templates from which the replaceme nt functions can be created. Such replacement functions may or may not call the original function, this is the same as Python decorators, but Dao decorators are typed and can be strictly typed. So all the static type checking that can be applied to normal functions c an also be applied to decorators as well. An equivalent Dao decorator for the above Python example is, 1 routine @Decorator( func(args): routine< =>int > ) 2 { 3 ret = func( args, ... ) # call the original function; 4 return ret + 123 5 } 6 routine Foo() 7 { 8 return 456 9 } 10 deco = @Decorator( Foo ) 11 deco() Where the parameter type routine< =>int > of @Decorator() indicates that this decorator c an only be applied to functions that can take no parameter and return an integer. args is a specially defined variable of tuple type to hold the parameters that will be passed to the decorated function. The ... in the end of the argument list indicates that the call m ust expand the previous tuple argument in the argument list, namely, removing the tuple a nd placing its items in the argument list. In both Python and Dao, decorators can be applied at function definition sites in the sam e way. 0.2 Decorators for Any Functions If one wants to define a decorator that can be applied to any functions. In Python, one m ight do, 1 def Decorator( func ): 2 def newfunc( *args, **kwargs ): 3 print "Calling with: %s, %s" % (args, kwargs) 4 return func( *args, **kwargs ) 5 return newfunc 6 7 def Foo( a ): 8 return a + 456 9 10 deco = Decorator( Foo ) 11 deco( 123 ) The equivalent in Dao would be, 1 routine @Decorator( func(args): routine ) 2 { 3 io.writeln( 'Calling with:', args, ... ) 4 return func( args, ... ) # call the original function; 5 } 6 routine Foo( a ) 7 { 8 return a + 456 9 } 10 deco = @Decorator( Foo ) 11 deco( 123 ) 0.3 Overloaded Decorators If one wants to write a decorator for multiple type of functions, in Python one would hav e to create decorators as in the above Python examples and check the argument types to ha ndle different types of functions. Because Python does not support function overloading. In Dao, one could simply create different decorators for different target functions, and overload them with the same name. For example, 1 routine @Decorator( func(args): routine<int=>int> ) 2 { 3 return func( args, ... ) + 123 4 } 5 routine @Decorator( func(args): routine<string=>string> ) 6 { 7 return func( args, ... ) + 'abc' 8 } 9 10 @Decorator # the first decorator will be applied; 11 routine Foo( a: int ) 12 { 13 return a * 100 14 } 15 16 @Decorator # the second decorator will be applied; 17 routine Foo( a: string ) 18 { 19 return a + '##'; 20 } 21 22 f = @Decorator( Foo ) 23 f( 123 ) 24 f( 'xyz' ) When the target function is also overloaded, the decorator will be applied to each of the overloaded functions, and create a new (and possible also overloaded as well) function.