On Sun, Jul 23, 2017 at 8:54 PM, Stephen J. Turnbull < turnbull.stephen...@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
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/