[Python-ideas] Conventions for function annotations

Nick Coghlan ncoghlan at gmail.com
Sun Dec 2 07:58:57 CET 2012


On Sun, Dec 2, 2012 at 4:26 PM, Robert McGibbon <rmcgibbo at gmail.com> wrote:

> By being *tolerant and well behaved when confronted with annotations that
> our library doesn't understand I*, I
> think we can use function annotations without a short-range decorator that
> translates their information in some other
> structure. If other annotation-using libraries are also willing to ignore
> our tabbing annotations if/when they encounter them,
> then can't we all get along smoothly?
> *
> *
> (For reference, the feature will look/work something like this)
>
> *
> In[1]: def foo(filename : tab_glob('*.txt')):  # tab completion that
> recommends files/directories that match a glob pattern
> ...          pass
> ...
> In[2]: foo(<TAB>
> 'a.txt'        'b.txt'
> 'c.txt'         'dir/'
> *
>

You're missing the other key reason for requiring decorators that interpret
function annotations: they're there for the benefit of *readers*, not just
other software. Given your definition above, I don't know what the
annotations are for, except by recognising the "tab_glob" call. However,
that then breaks as soon as the expression is put into a named variable
earlier in the file:

    def foo(filename : text_files): # What does this mean?
        pass

But the reader can be told *explicitly* what the annotations are related to
via a decorator:

    @tab_expansion
    def foo(filename : text_files): # Oh, it's just a tab expansion
specifier
        pass

Readers no longer have to guess from context, and if the tab_expansion
decorator creates IPython-specific metadata, then the interpreter doesn't
need to guess either.

(Note that you *can* use ordinary mechanisms like class decorators,
metaclasses, post-creation modification of classes and IDE snippet
inclusion to avoid the need to type out the "this is what these annotations
mean" decorator explicitly. However, that's just an application of Python's
standard abstraction tools, rather than a further special case convention)

Mixing annotations intended for different consumers is a fundamentally bad
idea, as it encourages unreadable code and complex dances to avoid stepping
on each other's toes. It's better to design a *separate* API that supports
composition by passing the per-parameter details directly to a decorator
factory (which then adds appropriate named attributes to the function),
with annotations used just as syntactic sugar for simple cases where no
composition is involved.

The important first question to ask is "How would we solve this if
annotations didn't exist?" and only *then* look at the shorthand case for
function-annotations. For cases where function annotations make code more
complex or less robust, *don't use them*.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20121202/4d60d2e3/attachment.html>


More information about the Python-ideas mailing list