<div class="gmail_quote">On Sun, Dec 2, 2012 at 2:30 AM, Thomas Kluyver <span dir="ltr"><<a href="mailto:thomas@kluyver.me.uk" target="_blank">thomas@kluyver.me.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think annotations are potentially very useful for things like introspection and static analysis. For instance, your IDE could warn you if you pass a parameter that doesn't match the type specified in an annotation. In these cases, the code reading the annotations isn't coupled with the function definitions.<br>


<br>I'm not aiming to restrict annotations, just to establish some conventions to make them useful. We have a convention, for instance, that attributes with a leading underscore are private. That's a useful basis that everyone understands, so when you do obj.<tab> in IPython, it doesn't </blockquote>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">show those attributes by default. I'd like to have some conventions of that nature around annotations.</blockquote>
<div><br></div>Indeed, composability is a problem with annotations. I suspect the only way to resolve this systematically is to adopt a convention where annotations are used *strictly* for short-range communication with an associated decorator that transfers the annotation details to a *different* purpose-specific location for long-term introspection.<br>
<br>Furthermore, if composability is going to be possible in general, annotations can really *only* be used as a convenience API, with an underlying API where the necessary details are supplied directly to the decorator. For example, here's an example using the main decorator API for a cffi callback declaration [1]:<br>
<br>    @cffi.callback("int (char *, int)"):<br>    def my_cb(arg1, arg2):<br>        ...<br><br>The problem with this is that it can get complicated to map C-level types to parameter names as the function signature gets more complicated. So, what you may want to do is write a decorator that builds the CFFI signature from annotations on the individual parameters:<br>
<br>    @annotated_cffi_callback<br>    def my_cb(arg1: "char *", arg2: "int") -> "int":<br>        ...<br><br>The decorator would turn that into an ordinary call to cffi.callback, so future introspection wouldn't look at the annotations mapping at all, it would look directly at the CFFI metadata.<br>
<br>Annotations should probably only ever be introspected by their associated decorator, and if you really want to apply multiple decorators with annotation support to a single function, you're going to have to fall back to the non-annotation based API for at least some of them. Once you start trying to overload the annotation field with multiple annotations, the readability gain for closer association with the individual parameters is counterbalanced by the loss of association between the subannotations and their corresponding decorators.<br>
<br>[1] <a href="http://cffi.readthedocs.org/en/latest/#callbacks">http://cffi.readthedocs.org/en/latest/#callbacks</a><br></div><br>Cheers,<br>Nick.<br clear="all"><br>-- <br>Nick Coghlan   |   <a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>   |   Brisbane, Australia<br>