On 11/01/2012 12:07 PM, Ian Kelly wrote:
On Thu, Nov 1, 2012 at 5:32 AM, Andrew Robinson
<andr...@r3dsolutions.com>  wrote:
Hmmmm.... was that PEP the active state of Python, when Tim rejected the bug 
report?
Yes. The PEP was accepted and committed in March 2006 for release in
Python 2.5.  The bug report is from June 2006 has a version
classification of Python 2.5, although 2.5 was not actually released
until September 2006.
That explain's Peter's remark.  Thank you.  He looks *much* smarter now.


Pep 357 merely added cruft with index(), but really solved nothing.  Everything 
index() does could be implemented in __getitem__ and usually is.
No.  There is a significant difference between implementing this on
the container versus implementing it on the indexes.  Ethan
implemented his string-based slicing on the container, because the
behavior he wanted was specific to the container type, not the index
type.  Custom index types like numpy integers on the other hand
implement __index__ on the index type, because they apply to all
sequences, not specific containers.

Hmmm...
D'Aprano didn't like the monkey patch;and sub-classing was his fix-all.

Part of my summary is based on that conversation with him,and you touched on one of the unfinished points; I responded to him that I thought __getitem__ was under-developed. The object slice() has no knowledge of the size of the sequence; nor can it get that size on it's own, but must passively wait for it to be given to it.

The bottom line is: __getitem__ must always *PASS* len( seq ) to slice() each *time* the slice() object is-used. Since this is the case, it would have been better to have list, itself, have a default member which takes the raw slice indicies and does the conversion itself. The size would not need to be duplicated or passed -- memory savings, & speed savings...

I'm just clay pidgeoning an idea out here....
Let's apply D'Aprano 's logic to numpy; Numpy could just have subclassed *list*; so let's ignore pure python as a reason to do anything on the behalf on Numpy:

Then, lets' consider all thrid party classes; These are where subclassing becomes a pain -- BUT: I think those could all have been injected.

>>> class ThirdParty( list ):  # Pretend this is someone else's...
...     def __init__(self): return
...     def __getitem__(self,aSlice): return aSlice
...

We know it will default work like this:
>>> a=ThirdParty()
>>> a[1:2]
slice(1, 2, None)

# So, here's an injection...
>>> ThirdParty.superOnlyOfNumpy__getitem__ = MyClass.__getitem__
>>> ThirdParty.__getitem__ = lambda self,aSlice: ( 1, 3, self.superOnlyOfNumpy__getitem__(aSlice ).step )
>>> a[5:6]
(1, 3, None)

Numpy could have exported a (workable) function that would modify other list functions to affect ONLY numpy data types (eg: a filter). This allows user's creating their own classes to inject them with Numpy's filter only when they desire;

Recall Tim Peter's "explicit is better than implicit" Zen?

Most importantly normal programs not using Numpy wouldn't have had to carry around an extra API check for index() *every* single time the heavily used [::] happened. Memory & speed both.

It's also a monkey patch, in that index() allows *conflicting* assumptions in violation of the unexpected monkey patch interaction worry.

eg: Numpy *CAN* release an index() function on their floats -- at which point a basic no touch class (list itself) will now accept float as an index in direct contradiction of PEP 357's comment on floats... see?

My point isn't that this particular implementation I have shown is the best (or even really safe, I'd have to think about that for a while). Go ahead and shoot it down...

My point is that, the methods found in slice(), and index() now have moved all the code regarding a sequence *out* of the object which has information on that sequence. It smacks of legacy.

The Python parser takes values from many other syntactical constructions and passes them directly to their respective objects -- but in the case of list(), we have a complicated relationship; and not for any reason that can't be handled in a simpler way.

Don't consider the present API legacy for a moment, I'm asking hypothetical design questions:

How many users actually keep slice() around from every instance of [::] they use? If it is rare, why create the slice() object in the first place and constantly be allocating and de-allocating memory, twice over? (once for the original, and once for the repetitive method which computes dynamic values?) Would a single mutable have less overhead, since it is destroyed anyway?

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to