[Python-ideas] Allow "assigning" to Ellipse to discard values.

Andrew Barnert abarnert at yahoo.com
Tue Feb 10 22:35:37 CET 2015


On Feb 10, 2015, at 13:01, Spencer Brown <spencerb21 at live.com> wrote:

> Basically, in any location where a variable name is provided for assignment (tuple unpacking, for loops, function parameters, etc) a variable name can be replaced by '...' to indicate that that value will not be used.

The idiomatic way to do this has always been to assign to _. All of your examples work today with _, and I don't think they look significantly better with .... (Of course _ has the problem that when it's being used for gettext in an app, it can't be used for the disposable variable in the same app, but people have dealt with that for decades without any major complaints.)

So the only real substance to your proposal is that it opens up the possibility for compiler optimizations. But most of these seem like pretty narrow possibilities. For example, you suggest that "for ... in range(100):" could be optimized to a simple C loop. But "for i in range(100):" could just as easily be optimized to a simple C loop. if you can prove that range is still the builtin and therefore this yields exactly 100 times so you can skip the __next__ calls, surely you can also prove that it yields exactly the first 100 ints, so you can still skip the __next__ calls even if you do want those ints.

But it's pretty hard for a static optimizer to prove that range is still range, so you really can't skip the __next__ even in the ellipsis case. 

Either way, the only thing you're saving is an assignment--an extra addref/decref pair and a pointer copy. That's not _nothing_, but it's not that big a deal compared to, say, a __next__ call, or a typical loop body. And if you really need to remove those, you could pretty easily remove dead local assignments, which would optimize everyone's existing code automatically, instead of requiring them to write new code that's incompatible with 3.4 to get the benefit. Presumably the reason CPython doesn't do this is that the small benefit has never been worth the time it would take for anyone to implement and maintain the optimization.


> This would be syntactically equivalent to del-ing the variable immediately after, except that the assignment never needs to be done.
> 
> Examples:
>>>> tup =  ('val1', 'val2', (123, 456, 789))
>>>> name, ..., (..., value, ...) = tup
> instead of:
>>>> name = tup[0]
>>>> value = tup[2][1]
> This shows slightly more clearly what format the tuple will be in, and provides some additional error-checking - the unpack will fail if the tuple is a different size or format.
> 
>>>> for ... in range(100):
>>>>   pass
> This particular case could be optimised by checking to see if the iterator has a len() method, and if so directly looping that many times in C instead of executing the __next__() method repeatedly.
> 
>>>> for i, ... in enumerate(object):
> is equivalent to:
>>>> for i in range(len(object)):
> The Ellipse form is slightly more clear and works for objects without len(). 
> 
>>>> first, second, *... = iterator
> In the normal case, this would extract the first two values, and exhaust the rest of the iterator. Perhaps this could be special-cased so the iterator is left alone, and the 3rd+ values are still available.
> 
>>>> def function(param1, ..., param3, key1=True, key2=False, **...):
>>>>    pass
> This could be useful when overriding functions in a subclass, or writing callback functions. Here we don't actually need the 2nd argument. The '**...' would be the only allowable form of Ellipse in keyword arguments, and just allows any other keywords to be given to the function.
> 
> - Spencer
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/


More information about the Python-ideas mailing list