Steve Holden wrote: > Kay Schluehr wrote: > > Mike Meyer wrote: > > > > > >>Yes, but the function "sorted" is more useful than a list method > >>"sorted" in a duck typing language. > > > > > > I don't see what this has to do with "duck typing"? sorted() is simply > > a generic function accepting different types. I'm not aware that > > sorted() requires a specific interface of those types it accepts. > > > Just because you aren't aware of something doesn't stop it being true. > The argument must be iterable, and there's a specific protocol for that. > > > >>The function sorted works on all iterators. I can do: > >> > Ah, so you *were* aware of it.
I already responded to it two days ago in the reply to Terry. No need to rehash that. > >> > >>>>>def t(n): > >>>>> for i in range(n): > >>>>> yield i > >>>>>... > >>>>>print sorted(t(5)) > >> > >>and have it work. > >> > >>If sorted were a method of a class - the it'd have to be implemented > >>again for every class iterable class. Either that, or you'd have to > >>create an abstract parent of all iterable classes to add it to - which > >>seems more appropriate for a B&D language than Python. > > > > > > Instead of extending a class hierarchy it might even be possible to > > hook a trait into the class by means of a __traits__ attribute. > > > > http://fsl.cs.uiuc.edu/~mhills/presentations/TraitsPresentation.pdf > > > > Generators as well as lists and tuples would provide a sortable trait. > > The sorted() function could remain available for convenience. > > > The advantage being ... ? Perhaps you have just discovered a really > interesting hammer, and are seeing this problem as a nail? I also responded to traits as nice-to-have but not essential. And please don't aggressively consider me as childish as you might be yourself. Adding a __traits__ attribute should enable the user adding methods to builtins in a safe manner. This has the advantage that one can apply methods to string or integer literals or even replace methods without touching the C sources. A very typical use case is integer representation. In 95% of all my business applications I don't have much use for decimal integer representation but want a hex rep in different variants: >>> 0x0F # current rep 15 >>> int.__traits__.append(HexRepTrait) # used for delegation of # __repr__ to the Trait >>> int.configure_format(HexRepTrait.HEXFORM_STD) # configure_format is a # hooked trait method >>> 0x0F 0F >>> 2*0x800 10 00 >>> print 700 02 BC I know I can write wrapper classes, because I do this all the time, but that's not the point: Python is essentially not about boiler-plate. And no, I also don't want to fight for each method and keyword with Guido. > > > >>And even if you do add the abstract class, how do you make my example > >>work without explictly converting the iterator to a list type? > > > > > > I don't know how sorted() is implemented? A naive implementation would > > in fact be nothing else then: > > > > def sorted(iter): > > l = list(iter) > > l.sort() > > return l > > > > Kay > > > That would indeed be a naïve implementation. And that's the real implementation: static PyObject * builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs; PyObject *callable; static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0}; long reverse; if (args != NULL) { if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", kwlist, &seq, &compare, &keyfunc, &reverse)) return NULL; } newlist = PySequence_List(seq); if (newlist == NULL) return NULL; callable = PyObject_GetAttrString(newlist, "sort"); if (callable == NULL) { Py_DECREF(newlist); return NULL; } newargs = PyTuple_GetSlice(args, 1, 4); if (newargs == NULL) { Py_DECREF(newlist); Py_DECREF(callable); return NULL; } v = PyObject_Call(callable, newargs, kwds); Py_DECREF(newargs); Py_DECREF(callable); if (v == NULL) { Py_DECREF(newlist); return NULL; } Py_DECREF(v); return newlist; } The crucial steps are the conversion from args to seq, the conversion from seq to newlist and finally calling PyObject_Call(callable, ...) where callable stores the sort method of newlist. By the way I don't see much use in implementing this trivial wrapper function in C except for the joy of refcounting ;) And now we take a look on how the PyPythonistas implemented sorted(): def sorted(lst, cmp=None, key=None, reverse=None): "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list" sorted_lst = list(lst) sorted_lst.sort(cmp, key, reverse) return sorted_lst Surprise, surprise! > The implementation is, of > course, an implementation detail ;-) In this case it requires that > sort() then provides all the magic - the need for magic doesn't go away! Has anyone denied the necessaty of sort()? Kay -- http://mail.python.org/mailman/listinfo/python-list