Re: [Python-ideas] A namedtuple literal.

(Attempting to reply to https://mail.python.org/pipermail/python-ideas/2014-April/027443.html)
In JS, if you want to define a simple object, you can write it in two ways: {'spam': 'ham'} or {spam: 'ham'} But when you have a key name defined in a variable, you'll need to do key = 'spam' o = {} o[key] = 'ham' Where in Python, you'd simply write {key: 'ham'}. So for Python, I think that having unquoted keys in literals is a bad idea.
I agree with this (even if you no longer do). There's no precedence (that I can think of) for NOT evaluating things before a colon, and nothing like using attr names (rather than objects that hold attribute names) with a colon. As long as we're just fooling around with ideas, here's an alternative proposal for namedtuple literal syntax[0]. I don't mean this as an actual suggestion, but I think it is better than unquoted keys before colons. ('color':c, 'position':c) #quoted, or with variables (color=c, position=c) #unquoted, with literals Example: p = (x=1, y=5) #type is something new, like `ntuple`, or just `namedtuple`. This is similar to keyword arguments, which don't have to quote their first parts. This can be generalized to dicts, to keep consistency. d = {'hello':1, 'world':2} #original d = {hello=1, world=2} #new and the earlier-proposed "ordered dict literal"[1] od = ['hello':1, 'world':2] #new od = [hello=1, world=2] #new new Or alternatively, with `=` just appearing in ntuples, this can be used: od = OrderedDict((hello=1, world=2)) which is interesting and also somehow horrifying. Some arguments against this: - Introducing `=` in yet another context. Ugly. - Tuples are ordered, and **kwargs are unordered[2], so there's a conceptual discontinuity there. - Accidentally writing `:` when you mean `=` can lead to silent bugs. - Extending the syntax to dictionaries possibly violates TOOWTDI, and not doing so feels inconsistent to me. I think about `(var_holding_spam: 1, literally_eggs=2)` and I'm like, "This is obviously two ways of doing it." - People might expect `p = (x=1) to be a 1-ntuple. I don't want it to be, and I don't like that it wouldn't be. I like the taste of the syntax (and the generalizations, and the OrderedDict literal), but I see how it isn't necessarily necessary (or welcome). [0] Found a mention of this here: https://mail.python.org/pipermail/python-ideas/2010-October/008489.html [1] Guido hated that: https://mail.python.org/pipermail/python-ideas/2009-June/004924.html [2] Making it ordered is obstructed by concerns about performance ( https://mail.python.org/pipermail/python-ideas/2013-February/019699.html). Currently being discussed here: https://mail.python.org/pipermail/python-ideas/2014-April/027454.html

On 15 April 2014 07:44, Franklin? Lee <leewangzhong+python@gmail.com> wrote:
As long as we're just fooling around with ideas, here's an alternative proposal for namedtuple literal syntax[0].
Isn't a namedtuple literal a bad idea? Isn't the point of a namedtuple (as distinct from a dict or OrderedDict), that each object only stores the data and the names are stored in the type, making having lots of namedtuples more memory efficient? ("Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples." -- https://docs.python.org/2/library/collections.html#collections.namedtuple) If you already have a specific namedtuple type instantiated, literals are easy: Point = namedtuple('Point', ['x', 'y']) Point(1,2) # positional Point(y=2, x=1) # named
- People might expect `p = (x=1) to be a 1-ntuple. I don't want it to be, and I don't like that it wouldn't be.
Adding a trailing comma like with normal 1-tuples to get "p = (x=1,)" would seem like the obvious approach? a=(b=1) is already invalid syntax though. Cheers, aj -- Anthony Towns <aj@erisian.com.au>

I don't see much of a necessary memory issue with namedtuple literals. Upon creation of an anonymous namedtuple, you can map the tuple of names to a single type object. Sample pseudo-code (*smirk*) implementation for what the interpreter could do, given the key-value pairs: def ntuple(pairs: OrderedDict): names = tuple(pairs.keys()) try: tuple_factory = existing_ntuples[names] except ValueError: tuple_factory = namedtuple(None, names) # `None` not actually legal for namedtuple's name param existing_ntuples[names] = tuple_factory return tuple_factory(*pairs.values()) A different (ideological?) problem: namedtuples look like they're basically made to be both tuples AND simple lightweight immutable *classes*. The namedtuple literal implemented this way would be effectively allowing reusable anonymous classes. I don't see too much of a problem with this, though, since we should usually not care if they're ducks or really monkeys. Here are some sample "abuses", though: a = (x=4, y=5) b = type(a)(6, 7) c = (x='snark', y='sarcasm') type(c) == type(b) #True Actually, now that I write it out, I like that the type of an anonymous named tuple depends on the property names, and that two anonymous ntuples with different keylists are different. On Mon, Apr 14, 2014 at 7:25 PM, Anthony Towns <aj@erisian.com.au> wrote:
On 15 April 2014 07:44, Franklin? Lee <leewangzhong+python@gmail.com> wrote:
As long as we're just fooling around with ideas, here's an alternative proposal for namedtuple literal syntax[0].
Isn't a namedtuple literal a bad idea? Isn't the point of a namedtuple (as distinct from a dict or OrderedDict), that each object only stores the data and the names are stored in the type, making having lots of namedtuples more memory efficient? ("Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples." -- https://docs.python.org/2/library/collections.html#collections.namedtuple)
If you already have a specific namedtuple type instantiated, literals are easy:
Point = namedtuple('Point', ['x', 'y']) Point(1,2) # positional Point(y=2, x=1) # named
- People might expect `p = (x=1) to be a 1-ntuple. I don't want it to be, and I don't like that it wouldn't be.
Adding a trailing comma like with normal 1-tuples to get "p = (x=1,)" would seem like the obvious approach? a=(b=1) is already invalid syntax though.
Cheers, aj
-- Anthony Towns <aj@erisian.com.au>
participants (2)
-
Anthony Towns
-
Franklin? Lee