Tail recursion to while iteration in 2 easy steps
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu Oct 3 21:30:19 EDT 2013
On Wed, 02 Oct 2013 22:41:00 -0400, Terry Reedy wrote:
> I am referring to constant-value objects included in the code object.
> >>> def f(): return (1,2,3)
>
> >>> f.__code__.co_consts
> (None, 1, 2, 3, (1, 2, 3))
Okay, now that's more clear. I didn't understand what you meant before.
So long as we understand we're talking about a CPython implementation
detail.
> None is present as the default return, even if not needed for a
> particular function. Every literal is also tossed in, whether needed or
> not.
>
>>>> which in Python 3.3 understands tuples like (1, 2, 3), but not lists.
>
> The byte-code does not understand anything about types. LOAD_CONST n
> simply loads the (n+1)st object in .co_consts onto the top of the stack.
Right, this is more clear to me now.
As I understand it, the contents of code objects are implementation
details, not required for implementations. For example, IronPython
provides a co_consts attribute, but it only contains None. Jython doesn't
provide a co_consts attribute at all. So while it's interesting to
discuss what CPython does, we should not be fooled into thinking that
this is guaranteed by every Python.
I can imagine a Python implementation that compiles constants into some
opaque object like __closure__ or co_code. In that case, it could treat
the list in "for i in [1, 2, 3]: ..." as a constant too, since there is
no fear that some other object could reach into the opaque object and
change it.
Of course, that would likely be a lot of effort for very little benefit.
The compiler would have to be smart enough to see that the list was never
modified or returned. Seems like a lot of trouble to go to just to save
creating a small list.
More likely would be implementations that didn't re-use constants, than
implementations that aggressively re-used everything possible.
--
Steven
More information about the Python-list
mailing list