And the interpetation of:

    def cat(infile: [doc("input stream"), opt("i")] = sys.stdin,
            outfile: [doc("output stream"), opt("o")] = sys.stdout
    ):

is likewise unambiguous, unless the creator of the documentation or option
features has defined some other interpretation for a list than "recursively
apply to contained items".  

The meaning is "unambiguous unless..." 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.

In which case, you need only do something like:

    def cat(infile: docopt("input stream", "i") = sys.stdin,
            outfile: docopt("output stream", "o") = sys.stdout
    ):

with an appropriate definition of methods for the 'docopt' type.

Given that there are an infinite number of tools in the universe that could be processing "doc" and "opt" 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.

Since many people seem to be unfamiliar with overloaded functions, I would
just like to take this opportunity to remind you that the actual overload
mechanism is irrelevant.  If you gave 'doc' objects a 'printDocString()'
method and 'opt' objects a 'setOptionName()' method, the exact same logic
regarding extensibility applies.  The 'docopt' type would simply implement
both methods.

This is normal, simple standard Python stuff; nothing at all fancy.

The context is a little bit different than standard duck typing.

Let's say I define a function like this:

def car(b):
 "b is a list-like object"
 return b[0]

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.

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?

Consider this potential case:

BobsDocumentationGenerator.py:

class BobsDocumentationGeneratorAnnotation:
    def __init__...
    def printDocument(self):
        print self.doc
    def sideEffect(self):
        deleteHardDrive()

def BobsDocumentationGenerator(annotation):
   if hasattr(annotation, "printDocument"):
       annotation.printDocument()

SamsDocumentationGenerator.py:

class SamsDocumentationGeneratorAnnotation:
    def __init__...
    def printDocument(self):
        return self.doc
    def sideEffect(self):
        email(self.doc, "[EMAIL PROTECTED]")

def SamsDocumentationGenerator(annotation):
   if hasattr(annotation, "printDocument"):
       print annotation.printDocument()
       annotation.sideEffect()

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)

One simple way to make it unambiguous would be to do a test more like:

   if hasattr(annotation, SamsDocumentationGenerator.uniqueObject): ...

The association of the unique object with an annotator object would be an explicit assertion of compatibility.

Can we agree that the PEP should describe strategies that people should use to make their annotation recognition strategies unambiguous and failure-proof?

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.

 Paul Prescod

_______________________________________________
Python-3000 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: 
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com

Reply via email to