Jay Parlar <[EMAIL PROTECTED]> wrote: > class A(object): > def foo(self): > print "bar" > > class B(object): > def foo(self): > print "bar" > > def typedfunction(x : A): > x.foo() > > b = B() > typedfunction(b) #Your system would probably consider this an error > > > This is an example of why type checking/hinting is no good, as it would > break duck typing. > > In terms of their definitions, A and B have nothing in common (ie. B > is not a subclass of A), yet I should be able to use instances of > either one, whenever the method 'foo' is expected. Type hinting would > completely break that. This again is why I point you in the direction > of PEP 246.
Indeed, as 246's paladin, my favorite interpretation of that "x: A" would be as equivalent to: def sanefunction(_x): x = adapt(_x, A) x.foo() So the code you give would raise a CantAdaptError, but only because no adapter has been registered from B to A -- easily fixed non-invasively e.g. by registering a DuckAdapter, basically to assert that homonimy IS all right between these classes. The reason I like the adaptation requirement (rather than explicit ducktyping being always in force by default) is to avoid the homonimy problem, a classic issue with large system -- imagine the following pieces all being independently defined...: class Lottery(object): def draw(self): ... class Artist(object): def draw(self): ... ... def runLotteryWithPortraitAsPrize(lottery, artist): winner = lottery.draw() portrait = museum.add(artist.draw()) ceremony('Award Prizes', winner, portrtait) ... runLotteryWithPortraitAsPrize(Artist(), Lottery()) Oops -- "draw" means completely different and unrelated things in different semantic domains, ducktyping doesn't work well here, and we're placing (a photo of) the winner in the "museum" (presumably a web photo gallery;-) and awarding the winner to the portrait, what a mess...!-) OK, not a realistic usecase;-), but method homonimy may indeed happen, and in large enough systems it may be a cause of some rare but hard-to-find bugs -- unittests don't nail them, because they're more in the nature of system integration problems (until the mistaken call, everything's hunky dory). Without adaptation -- if your only alternative was type-testing of some kind -- the inflexibility in gluing together disparately designed frameworks would probably be too high a price to pay, and you'd go for ducktyping and take your lumps. But adaptation (could I but convince Guido about it...!) lets you have most of the flexibility back (and then some, because you can easily adjust for name differences too;-) AND still make such problems easy to find (since they'll raise an exception when they occur). The nature of what exactly is a "protocol" (what we adapt to) is quite a secondary issue -- be it a mere interface, a type loosely standing for a host of semantics implications, an interface+DbC+pragmatics, whatever, being able to request adaptation (rather than merely checking compliance, isinstance for types, etc) is STILL a huge gain. Ah well... Alex -- http://mail.python.org/mailman/listinfo/python-list