At 12:58 PM 4/7/2006 -0700, "Eli Stevens (WG.c)" <[EMAIL PROTECTED]> wrote: >Guido van Rossum wrote: > > Did you forget duck typing? Something can be a sequence without > > subclassing a common base class. > ></lurk> > >I'm curious what effect overloaded functions will have on duck typing; a >Something can act like a list, but from my understanding of the >discussion* it won't end up matching: > >@pprint.register(list) >def pprint_list(obj): > pass
Note that this doesn't work *now* with pprint, even if you actually *subclass* list. At least with this approach, subclassing list would work automatically. :) >It seems to me that now to get a duck-typed list, not only do you have >to implement all of special methods that define "listy-ness," you also >have to find the overloaded functions that are specialized for lists, >and register your own implementation (or an implementation specialized >for lists, if appropriate). It's true that generic functions do not by themselves resolve the question of what "listy-ness" is. Your comment does highlight the idea, however, that it would be useful to be able to use duck typing to target generic function methods. For example, to say that "this method is usable against any object that can have these other functions called on it". A kind of mapping from an operation to dependent operations, such that you can define a generic "operator.getslice" method for any object that can be used with the "operator.getitem" generic function. This sort of goes back to the "monkey typing" proposal I made early last year in response to the last big python-dev debate on adaptation. Monkey typing is in fact just generic functions combined with a kind of "universal adapter" type, that allows you to treat generic functions as methods of the adapter object, rather than calling them as functions. In fact, this is very close to what the Haskell programming language calls "typeclasses". A typeclass in Haskell is basically a set of generic functions that apply to some type. You declare an "instance" of a typeclass by specifying the operations that correspond to the operations in the typeclass, which then allows your new type to be used by any code that expects the typeclass. So, in Haskell you could define "listyness" by declaring a typeclass that included various listy generic functions (setitem, getitem, insert, delitem, and len, perhaps). Then, to declare your new listy type, you would merely need to specify what functions or methods of your type corresponded to the "listy" generic functions. Since other functions' methods can be defined in terms of listyness, there's no need for you to register for all possible things everywhere that take listy things. You may be wondering why typeclasses aren't the same thing as protocols or interfaces. The key difference is that a typeclass is defined in terms of *independent operations*. A typeclass is basically a collection of related generic functions, *not* a specification of a type's behavior. This means that operations can be *shared* between typeclasses. This is crucial, I think, to Python, where we have some very "fat" interfaces that can be defined using different method subsets. For example, "read file" vs. "write file": both have a "close()" method. Using traditional interface concepts found in Python and Java, you would have to declare two different interfaces, or create a "read-write" file interface in order to handle this. With typeclasses, however, the notion of "close()" can be independent, and you can assemble new typeclasses as needed by simply referring to the operations needed. And -- the most crucial point -- when somebody defines a new typeclass composed only of existing operations that your type can support, then your type gets to play without anybody making any additional declarations at all. This to me seems more Pythonic than traditional interfaces, as it allows something that's essentially just duck typing, but based on *objects* (the generic functions) rather than *names*. Where an interface is a namespace that defines operations, a typeclass is defined by the operations that comprise it. Thus, a typeclass for "duck" is just shorthand for some set of behaviors like walking and quacking. _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com