[Numpy-discussion] Release of 1.0b5 this weekend

Charles R Harris charlesr.harris at gmail.com
Tue Aug 29 18:42:23 EDT 2006


On 8/29/06, Tim Hochberg <tim.hochberg at ieee.org> wrote:
>
> David M. Cooke wrote:
> > On Tue, 29 Aug 2006 14:03:39 -0700
> > Tim Hochberg <tim.hochberg at ieee.org> wrote:
> >
> >
> >> Of these,  clip, conjugate and round support an 'out' argument like
> that
> >> supported by ufunces;  byteswap has a boolean argument telling it
> >> whether to perform operations in place; and sort always operates in
> >> place. Noting that the ufunc-like methods (max, argmax, etc) appear to
> >> support the 'out' argument as well although it's not documented for
> most
> >> of them, it looks to me as if the two odd methods are byteswap and
> sort.
> >> The method situation could be made more consistent by swapping the
> >> boolean inplace flag in byteswapped with another 'out' argument and
> also
> >> having sort not operate in place by default, but also supply an out
> >> argument there. Thus:
> >>
> >> b = a.sort()   # Returns a copy
> >> a.sort(out=a) # Sorts a in place
> >> a.sort(out=c) # Sorts a into c (probably just equivalent to c = a.sort
> ()
> >> in this case since we don't want to rewrite the sort routines)
> >>
> >
> > Ugh. That's completely different semantics from sort() on lists, so I
> think
> > it would be a source of bugs (at least, it would mean keeping two
> different
> > ideas of .sort() in my head).
> >
> Thinking about it a bit more, I'd leave sort alone (returning None and
> all).. I was (over)reacting to changing to sort to return self, which
> makes the set of methods both less consistent within itself, less
> consistent with python and more error prone IMO, which seems the worst
> possibility.


Here is Guido on sort:

I'd like to explain once more why I'm so adamant that *sort*() shouldn't
*return* 'self'.

This comes from a coding style (popular in various other languages, I
believe especially Lisp revels in it) where a series of side effects
on a single object can be chained like this:

  x.compress().chop(y).*sort*(z)

which would be the same as

  x.compress()
  x.chop(y)
  x.*sort*(z)

I find the chaining form a threat to readability; it requires that the
reader must be intimately familiar with each of the methods.  The
second form makes it clear that each of these calls acts on the same
object, and so even if you don't know the class and its methods very
well, you can understand that the second and third call are applied to
x (and that all calls are made for their side-effects), and not to
something else.

I'd like to reserve chaining for operations that *return* new values,
like string processing operations:

  y = x.rstrip("\n").split(":").lower()

There are a few standard library modules that encourage chaining of
side-effect calls (pstat comes to mind).  There shouldn't be any new
ones; pstat slipped through my filter when it was weak.

So it seems you are correct in light of the Python philosophy. For those
operators that allow specification of out I would still like to see a
special value that means inplace, I think it would make the code clearer. Of
course, merely having the out flag violates Guido's intent. The idea seems
to be that we want some way to avoid allocating new memory. So maybe
byteswap should be inplace and return None, while a copyto method could be
added. Then one would do

a.copyto(b)
b.byteswap()

instead of

b = a.byteswap()

-tim


Chuck
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20060829/b329ec82/attachment.html>


More information about the NumPy-Discussion mailing list