Confused about pep 318

Bengt Richter bokr at oz.net
Fri Aug 6 14:58:00 EDT 2004


On Thu, 5 Aug 2004 21:16:00 -0500, Skip Montanaro <skip at pobox.com> wrote:

>
>    Bengt> I too am very much against wasting '@' on @decorator!
>
>We could just switch completely to Unicode.  Then we'd have all sorts of
>punctuation characters available.  How about
>
>    # -*- coding: utf-8 -*-
>    \xe2\x98\xbadecorator
>    def f():
>        pass
>
>?
Yes, but then plain ascii editors would have an obscurity problem.
If you really want this context-sensitive function-stacking operator
whose stack is popped and applied to the result of the next def until
the stack is empty (is this effectively the rule?), why not just
leave it ascii encoded ;-)

     :)decorator
     def f():
         pass

Hm, perhaps '@' could be the beginning of a hidden Forth syntax for python? ;-)

BTW, can anything (blank lines, comments, assignment statements) come between the
@decorator line and the function def? Can the decorator line be conditional? E.g.,
    if __debug__: @add_my_debug_printouts
    def foo(x,y): return x+y

BTW2, is @something a purely a prefixed extension of def syntax, or is it
a dynamic, code-generating operator that really does stack functions to
be used when the very next function-definition code (not the callable function code)
executes? If so, is @(expression) acceptable? I.e., could you write (untested ;-)
    @(lambda f: (lambda *args,**kwargs: long(f(*args,**kwargs))))
instead of
    @force_long_result
? I don't guess so ;-)

Could you use a module attribute expression?

    @mydecorators.force_long_result

Why not? (I don't have a copy of 2.4 to play with (nor the time :-( )

But then, why an internal single anonymous stack to pop decorator functions from?
Why not use a named function source, that a programmer can control? That has an API
or protocol(usage?), so a programmer-defined object can override the functionality?

But if you have a named stack object, it could as well have ordinary methods for stack
access, and we wouldn't need a special stack-function-for-a-narrowly-defined-purpose
operator spelled '@' ;-) (BTW, does '@' stack functions or function names, actually?
I.e., does some_name have to be bound prior to the '@some_name' line? If names are
stacked, is a dotted name permissible? Probably not, right ;-)

You could define a stack object that would push args of __call__ so your syntax could be
    decorate = __builtins__.metafunctions.push # say you prefer 'decorate' as name
    ...   
    decorate(accepts_ints, returns_longs)
    def foo(x,y): return long(x+y)
or
    decorate(accepts_ints)
    decorate(returns_longs)
    def foo(x,y): return long(x+y)

You'd just have to arrange for def to use metafunctions.pop (hence overridable, if
you want to shadow the standard metafunctions object in builtins) to get decorator
functions. Of course a user-friendly alias for metafunctions.push could also exist
in builtins. That's just a matter of choosing a name ("at_sign" ;-)

(See other post for other angles on using a builtin object (and associated class)
-- though the idea mix is evolving, and there are no warranties express or implied
against contradiction or for version compatibility among them ;-)

I know I have thrown out too many ideas to make a forceful pitch for any one of them.
I just want to illustrate that there may yet be unthought-of alternatives to '@' that
are more object-oriented and general, with potentially not that different a syntax
in actual use, I.e.,
    AT(decorator) # assuming you like 'AT' as an alias
vs
    @decorator

My USD.02

Regards,
Bengt Richter



More information about the Python-list mailing list