code: def decorator(caller, func=None):
      
      if func is None: # returns a decorator
          fun = FunctionMaker(caller)
          first_arg = inspect.getargspec(caller)[0][0]
          src = 'def %s(%s): return _call_(caller, %s)' % (
              caller.__name__, first_arg, first_arg)
          return fun.make(src, dict(caller=caller, _call_=decorator),
                          undecorated=caller)
      else: # returns a decorated function
          fun = FunctionMaker(func)
          src = """def %(name)s(%(signature)s):
      return _call_(_func_, %(signature)s)"""
          return fun.make(src, dict(_func_=func, _call_=caller), undecorated=func)
docs: decorator(caller) converts a caller function into a decorator;
      decorator(caller, func) decorates a function using a caller.