
On Sun, Jul 23, 2017 at 8:54 PM, Stephen J. Turnbull < turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
C Anthony Risinger writes:
A tuple is a tuple is a tuple. No types. Just convenient accessors.
That's not possible, though. A *tuple* is an immutable collection indexed by the natural numbers, which is useful to define as a single type precisely because the natural numbers are the canonical abstraction of "sequence". You can use the venerable idiom
X = 0 Y = 1
point = (1.0, 1.0) x = point[X]
to give the tuple "named attributes", restricting the names to Python identifiers. Of course this lacks the "namespace" aspect of namedtuple, where ".x" has the interpretation of "[0]" only in the context of a namedtuple with an ".x" attribute. But this is truly an untyped tuple-with-named-attributes.
However, once you attach specific names to particular indexes, you have a type. The same attribute identifiers may be reused to correspond to different indexes to represent a different "convenience type". Since we need to be able to pass these objects to functions, pickle them, etc, that information has to be kept in the object somewhere, either directly (losing the space efficiency of tuples) or indirectly in a class-like structure.
I see the convenience of the unnamed-type-typed tuple, but as that phrase suggests, I think it's fundamentally incoherent, a high price to pay for a small amount of convenience.
Note that this is not an objection to a forgetful syntax that creates a namedtuple subtype but doesn't bother to record the type name explicitly in the program. In fact, we already have that:
>>> from collections import namedtuple >>> a = namedtuple('_', ['x', 'y'])(0,1) >>> b = namedtuple('_', ['x', 'y'])(0,1) >>> a == b True >>> c = namedtuple('_', ['a', 'b'])(0,1)
This even gives you free equality as I suppose you want it:
>>> a == c True >>> a.x == c.a True >>> a.a == c.x Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: '_' object has no attribute 'a' >>> c.x == a.a Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: '_' object has no attribute 'x'
Bizarre errors are the inevitable price to pay for this kind of abuse, of course.
I'm not a fan of syntaxes like "(x=0, y=1)" or "(x:0, y:1)", but I'll leave it up to others to decide how to abbreviate the abominably ugly notation I used.
Sure sure, this all makes sense, and I agree you can't get the accessors without storing information, somewhere, that links indexes to attributes, and it makes complete sense it might be implemented as a subtype, just like namedtuple works today. I was more commenting on what it conceptually means to have the designation "literal". It seems surprising to me that one literal has a different type from another literal with the same construction syntax. If underneath the hood it's technically a different type stored in some cached and hidden lookup table, so be it, but on the surface I think most just want a basic container with simpler named indexes. Every time I've used namedtuples, I've thought it more of a chore to pick a name for it, because it's only semi-useful to me in reprs, and I simply don't care about the type, ever. I only care about the shape for comparison with other tuples. If I want typed comparisons I can always just use a class. I'd also be perfectly fine with storing the "type" as a field on the tuple itself, because it's just a value container, and that's all I'll ever want from it. Alas, when I think I want a namedtuple, I usually end up using a dict subclass that assigns `self.__dict__ = self` within __new__, because this makes attribute access (and assignment) work automagically, and I care about that more than order (though it can be made to support both). At the end of the day, I don't see a way to have both a literal and something that is externally "named", because the only ways to pass the name I can imagine would make it look like a value within the container itself (such as using a literal string for the first item), unless even more new syntax was added. -- C Anthony