c[:]()

Warren Stringer warren at muse.com
Thu May 31 23:17:07 EDT 2007


As mentioned a while back, I'm now predisposed towards using `do(c)()`
because square brackets are hard with cell phones. The one mitigating factor
for more general use, outside of cell phones, is speed. If a PEP enables a
much faster solution with c[selector()]() then it may be worthwhile. But, I
feel a bit circumspect about suggesting a change as I haven't looked at
Python source, nor have I looked at the BNF, lately. I think Martelli's
recent post on implantation may be relevant:

> Tuples are implemented as compact arrays of pointer-to-PyObject (so are
> lists, BTW).  So, for example, a 10-items tuple takes 40 bytes (plus a
> small overhead for the header) on a 32-bit build, not 80 as it would if
> implemented as a linked list of (pointer-to-object, pointer-to-next)
> pairs; addressing sometuple[N] is O(1), NOT O(N); etc, etc.

The questions about implementing a working c[:]() are:
	1) Does it break anything?
	2) Does it slow anything down?
	3) Could it speed anything up?
	4) Does it make code easier to read?
 	5) What question(s) did I forget to ask?

1) No? The fact that c() currently fails on a container implies that
enabling it would not break existing client code. Would this break the
language definition? A couple years ago, I hand transcribed the BNF of
version 2.2 to an alternative to BNF. I would love to know if c[:]() would
break the BNF in a fundamental way. 

2) I don't know. I've always assumed that Python objects are hash table
entries. How would this change? Would it change? Does the message
"TypeError: 'list' object is not callable" guarantee a short path between
bytecode and hash table? Is there some other mitigating factor?

3) Maybe? Does overriding __call__ create any extra indirection? If yes,
then I presume that `do(c)()` would be slower the `c[:]()`. I am writing
rather amorphous code. This may speed it up.

4) I posit yes. Am I missing something? What idiom does would c[:]() break?
This correlates with whether `c[:]()` breaks the language definition, in
question 1)


Erik Max Francis wrote:
> Warren Stringer wrote:
> 
> > I'm still a bit new at this, was wondering why c[:]() doesn't work, and
> > implicitly wondering why it *shouldn't* work.
> 
> It does work.  It means "make a sliced copy of `c`, and then call it
> with no arguments."  Functionally that is _no different_ from `c()`,
> which means "take `c` and call it with no arguments," because presuming
> `c` is a list, `c[:]` makes a shallow copy.
> 
> So if you think `c()` and `c[:]()` should do something different in this
> case, you are profoundly confused about Python's semantics of what
> objects are, what it means to shallow copy a list, and what it means to
> make a function call.  That you keep including the slice suggests that
> there's something about its meaning that's not yet clicking.

I use `c[:]()` because it is unambiguous about using a container
 
> If you really want syntax where a function call on a container calls all
> of its elements, then that is trivially easy to do by creating such an
> object and overriding its `__call__` method.
> 
> If you're not willing to do that, but still insisting that `c[:]()`
> makes sense, then perhaps it would be more advisable to learn more about
> Python rather than try to suggest profound changes to the language and
> its conventions.

You're right. At the same time, version 3 is coming up soon. There is a
short window of opportunity for profound changes. 

Also, my audacious suggestion has spawned illuminating replies. For this
instance, I have read about shallow copy, before, but haven't been told
where it is used, before now. Other posts led to insights about closures,
and yielding a real solution. This is incredibly useful. I've learned a lot.

Thanks,

\~/




More information about the Python-list mailing list