> Instead of the compiler, could the _runtime_ be made smart enough to
> recognize that 'range' is being invoked in a context where a list isn't
> truly needed? Seems to me this use in 'for' is the only one worth
> special-casing (I've never seen, e.g., someone write 'if i in range(n)',
> or other non-for contexts where a list isn't needed).
Hmm, I suppose the compiler could recognize the range() call and
generate an instruction to set a hint flag that would be picked up by
the built-in range(). Will think about it some more...
> If this is the way to do it, I'd rather that range be left alone & a new
> builtin introduced. Think of all the Sieve of Eratosthenes programs
> you'll break otherwise <wink>.
Really? Actually the only non-for-loop use of range() I can imagine
is your "enumerated values" trick:
[red, green, blue] = range(3)
> Or perhaps range could return an object of this new non-storing type, and
> that also magically transforms itself into a vanilla list if used in a
> context that requires a genuine list (including, but not limited to, the
> "copy" context mentioned by Dirk). In fact, I like this one best of all
> -- users wouldn't need to know the non-storing type existed. It's
> an implementation hack, as it should be <grin>.
Jack proposed this too. It appears possible: when a
true-list-specific operation is called for, just update the
structure's contents and patch the type pointer, assuming a range
object takes no more space than a list object. However we rejected it
because it would lead to a very obscure class of errors: there is code
around which compares an object's type with type([]) and this would
fail very mysteriously on range objects: for all practical purposes
they behave as lists, but not when their type is taken...
--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
PS Tim: you got an earlier draft of this letter which accidentally
attributed the enum trick to Steve -- sorry about that! The list
archives unambiguously show that you proposed it first :-)