On Thu, 08 Nov 2012 18:00:58 -0700, Ian Kelly wrote: > On Thu, Nov 8, 2012 at 4:33 PM, Steven D'Aprano > <steve+comp.lang.pyt...@pearwood.info> wrote: >> On Thu, 08 Nov 2012 20:34:58 +0300, Andriy Kornatskyy wrote: >> >>> People who come from strongly typed languages that offer interfaces >>> often are confused by lack of one in Python. Python, being dynamic >>> typing programming language, follows duck typing principal. It can as >>> simple as this: >>> >>> assert looks(Foo).like(IFoo) >> >> How very cute. And I don't mean that in a good way. >> >> Why is this a class with a method, instead of a function that takes two >> class arguments (plus any optional arguments needed)? >> >> looks_like(Foo, IFoo) >> >> is less "cute", reads better to English speakers, and much more >> Pythonic. This isn't Java, not everything needs to be a class. > > I disagree. Does that test whether Foo looks like IFoo, or IFoo looks > like Foo?
What's the difference? "Looks like" is a symmetric comparison, like "equal" and "almost equal", but not "subset", "less than" etc. If x looks like y, then necessarily y must look like x. If Katy Perry looks like Zooey Deschanel, then it stands to reason that Zooey Deschanel looks like Katy Perry. James Woods looks like Erwin Schroedinger, and Erwin Schroedinger looks like James Woods. http://tvrefill.com/wp-content/uploads/2010/12/zooey-deschanel.jpg http://cheezburger.com/6704400128 So in that sense, looks(Spam).like(Ham) must always be the same as looks(Ham).like(Spam), and the order of operators doesn't matter. But that's not what we want! And to his credit, that's not what Andriy Kornatskyy's code actually implements. The problem is with the name, which is actively misleading by suggesting a symmetrical comparison for one which is not symmetrical. Suppose we want to make a movie with Zooey Deschanel, but she's not available, so we want a replacement who is duck-type compatible with her. The replacement doesn't need to be a Deschanel sister, but she does need to do *at least* everything Zooey can do. If she can do more, that's fine, but she can't do less. Since Katy Perry can do everything Zooey can do, PLUS she sings, we can replace Zooey with Katy: Katy is duck-type compatible with Zooey. But we can't replace Katy with Zooey, because Zooey can't sing.[1] (I think... I really don't actually know if Zooey Deschanel can sing or not. Just go along with the example.) The point I am making is that "looks like" is not a good description for this function. "Looks like" must be symmetrical, but the function we actually want is not symmetrical. It is actually a "subset" type relationship: given "looks(Zooey).like(Katy)", it checks that the public methods etc. of Zooey are a subset of the methods of Katy. That is, that instances of Katy can be used instead of instances of Zooey. Or is it the other way? Damned if I know. Let's find out: class Zooey: def act(self): pass class Katy: def act(self): pass def sing(self): pass py> looks(Zooey).like(Katy) __main__:2: UserWarning: 'sing': is missing. False I guessed wrong. The looks.like method as implemented tests that the right-hand size operand is a subset of the right-hand-side: py> looks(Katy).like(Zooey) True I argue that this is the wrong way around. (Even if it isn't the wrong way around, it certainly isn't clear or obvious which way you have to write the operands!) Consider this use-case: candidates = [Hilary, Jennifer, Katy] expected = looks(Zooey) # instantiate the looks class once only for actor in candidates: if expected.like(actor): make_movie_with(actor()) That's much nicer and more efficient than the way you have to write it now: candidates = [Hilary, Jennifer, Katy] for actor in candidates: # instantiate the looks class every time we want to test another class if looks(actor).like(Zooey): make_movie_with(actor()) So... it's a cute name, that sounds English-like. But it doesn't actually describe what the function does, it is wasteful for at least one useful use-case, and it's not clear which order you have to supply the two arguments. > looks(Foo).like(IFoo), on the other hand, is crystal clear about which > argument is which. I hope that by now you can see why I say that it is as clear as mud. [1] Some people might argue that neither can Katy Perry. -- Steven -- http://mail.python.org/mailman/listinfo/python-list