<br><div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">And the interpetation of:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;def cat(infile: [doc(&quot;input stream&quot;), opt(&quot;i&quot;)] = 
sys.stdin,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outfile: [doc(&quot;output stream&quot;), opt(&quot;o&quot;)] = sys.stdout<br>&nbsp;&nbsp;&nbsp;&nbsp;):<br><br>is likewise unambiguous, unless the creator of the documentation or option<br>features has defined some other interpretation for a list than &quot;recursively
<br>apply to contained items&quot;.&nbsp;&nbsp;</blockquote><div><br>The meaning is &quot;unambiguous unless...&quot; then it ambiguous. So as per my previous proposal I think that you and I agree that we should disallow the stupid interpretation by encoding the obvious one in the PEP.
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">In which case, you need only do something like:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;def cat(infile: docopt(&quot;input stream&quot;, &quot;i&quot;) = 
sys.stdin,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outfile: docopt(&quot;output stream&quot;, &quot;o&quot;) = sys.stdout<br>&nbsp;&nbsp;&nbsp;&nbsp;):<br><br>with an appropriate definition of methods for the 'docopt' type.</blockquote><div><br>Given that there are an infinite number of tools in the universe that could be processing &quot;doc&quot; and &quot;opt&quot; annotations, how would the user KNOW that there is one out there with a stupid interpretation of lists? They might annotate thousands of classes before finding out that some hot tool that they were planning to use next year is incompatible. So let's please define a STANDARD way of attaching multiple annotations to a parameter. Lists seem like a no-brainer choice for that.
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Since many people seem to be unfamiliar with overloaded functions, I would<br>
just like to take this opportunity to remind you that the actual overload<br>mechanism is irrelevant.&nbsp;&nbsp;If you gave 'doc' objects a 'printDocString()'<br>method and 'opt' objects a 'setOptionName()' method, the exact same logic
<br>regarding extensibility applies.&nbsp;&nbsp;The 'docopt' type would simply implement<br>both methods.<br><br>This is normal, simple standard Python stuff; nothing at all fancy. </blockquote><div><br>The context is a little bit different than standard duck typing.
<br><br>Let's say I define a function like this:<br><br>def car(b):<br>&nbsp;&quot;b is a list-like object&quot;<br>&nbsp;return b[0]<br><br>Then someone comes along and does something I never expected. They invent a type representing a list of bits in a bitfield. They pass it to my function and everything works trivially. But there's something important that happened. The programmer ASSERTED by passing the RDF list to the function 'a' that it is a list like object. My code wouldn't have tried to treat it as a list if the user hadn't passed it as one explicitly.
<br><br>Now look at it from the point of view of function annotations. As we said before, the annotations are inert. They are just attached. There is some code like a type checker or documentation generator that comes along after the fact and scoops them up to do something with them. The user did not assert (at the language level!) that any particular annotation applies to any particular annotation processor. The annotation processor is just looking for stuff that it recognizes. But what if it thinks it recognizes something but does not?
<br><br>Consider this potential case:<br><br>BobsDocumentationGenerator.py:<br><br>class BobsDocumentationGeneratorAnnotation:<br>&nbsp;&nbsp;&nbsp; def __init__...<br>&nbsp;&nbsp;&nbsp; def printDocument(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print self.doc<br>&nbsp;&nbsp;&nbsp; def sideEffect(self):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteHardDrive()<br><br>def BobsDocumentationGenerator(annotation):<br>&nbsp;&nbsp; if hasattr(annotation, &quot;printDocument&quot;):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; annotation.printDocument()<br><br>SamsDocumentationGenerator.py:<br><br>class SamsDocumentationGeneratorAnnotation:
<br>
&nbsp;&nbsp;&nbsp; def __init__...<br>&nbsp;&nbsp;&nbsp;
def printDocument(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self.doc<br>&nbsp;&nbsp;&nbsp; def sideEffect(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email(self.doc, &quot;python-dev@pytho...&quot;)<br><br>def SamsDocumentationGenerator(annotation):<br>
&nbsp;&nbsp; if hasattr(annotation, &quot;printDocument&quot;):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print annotation.printDocument()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; annotation.sideEffect()<br>
<br>These objects, _by accident_ have the same method signature but different side effects and return values. Nobody anywhere in the system made an incorrect assertion. They just happened to be unlucky in the naming of their methods. (unbelievably unlucky but you get the drift)
<br><br>One simple way to make it unambiguous would be to do a test more like:<br><br>
&nbsp;&nbsp; if hasattr(annotation, SamsDocumentationGenerator.uniqueObject): ...<br><br>The association of the unique object with an annotator object would be an explicit assertion of compatibility.<br><br>Can we agree that the PEP should describe strategies that people should use to make their annotation recognition strategies unambiguous and failure-proof?
<br><br>I think that merely documenting appropriately defensive techniques might be enough to make Talin happy. Note that it isn't the processing code that needs to be defensive (in the sense of try/catch blocks). It is the whole recognition strategy that the processing code uses. Whatever recognition strategy it uses must be unambiguous. It seems like it would hurt nobody to document this and suggest some unambiguous techniques.
<br><br>&nbsp;Paul Prescod<br><br></div></div>