On Sat, Apr 18, 2020 at 02:13:51PM +0200, Alex Hall wrote: > My issue with this, and maybe it's what Andrew is also trying to say, is > that it breaks our usual assumptions about composing expressions. `{u, v}` > is an expression, it represents a set, and it always represents that > wherever you put it. Under your proposal, these two programs are both valid > syntax with different meanings: > > f(**{u, v}) > > x = {u, v} > f(**x)
True, and that does count as a (minor?) point against it. But not one that I think should rule it out. > Is there anything else similar in the language? Obviously there are cases > where the same text has different meanings in different contexts, but I > don't think you can ever refactor an expression (or text that looks like an > expression) into a variable and change its meaning while keeping the > program runnable. Of course! There are many ways that this can occur. f(a, b, c) x = a, b, c f(x) are very different things. Here's another one: import name x = name import x Here's a third: del fe, fi, fo, fum x = fe, fi, fo, fum del x Here's an example so obvious (and trivial) that I'm almost embarrassed to include it: seq[index] x = [index] seqx If code is made of composable building blocks, those blocks aren't *characters*. What makes a composable block is dependent on context. To make up for how trivial the previous example was, here's a complicated one: for item in items: if item: continue do_stuff() versus: def block(item): if item: continue do_stuff() for item in items: block() I have often wished I could refactor continue and break into functions, but you can't :-( Although in this case at least you get a syntax error when you try. Here's an example with sequence unpacking: a = [1, 2, *seq] x = 2, *seq a = [1, x] Another example: class MyClass(metaclass=MyMeta) metaclass = MyMeta class MyClass(metaclass) That's just a special case of keyword notation itself: func(x=expr) x = expr func(x) Those are not the same, unless the first positional argument happens to be named `x`. And one final example: class C: def method(self): pass versus: def method(self): pass class C: method This is not an exhaustive list, just the first few things that came to my mind. > This proposal makes it harder for beginners to understand how a program is > interpreted. It breaks the simple mental model where building blocks are > combined in a consistent fashion into larger parts. I **LOVE** the ability to reason about code with a simple mental model of building blocks. I would consider it a very important property of syntax. But it is not an absolute requirement in all things. I mean, we wouldn't want to say that function call syntax `f(x, y, z)` is a disaster because it looks like we combined a name with a tuple. I acknowledge that "cannot compose this" is a point against it, but I deny that it should be a flat out disqualification. There are lots of things in Python that cannot be trivially composed. > The example above looks a bit dumb, but maybe users will try: > > ``` > if flag: > kwargs = {u, v} > else: > kwargs = {w, x} > f(**kwargs) > ``` I think this point will apply to all(?) such syntactic proposals. I don't think this scenario is too different from this: if flag: f(u=expr1, v=expr2) else: f(w=expr3, x=expr4) If you want to refactor that, you can't do this: f((u=expr1, v=expr2) if flag else (w=expr3, x=expr4)) but you can just use regular dict unpacking: d = dict(u=expr1, v=expr2) if flag else dict(w=expr3, x=expr4) f(**d) > Which is valid syntax but is wrong. Then they might try changing that to: > > f(**({u, v} if flag else {w, x})) > > which is suddenly invalid syntax. Not invalid syntax, but it's still wrong. You'll get a TypeError when trying to `**` unpack a set instead of a dict. > This is a very weird user experience. On > that note, is this valid? > > f(**({u, v})) I would expect that to parse as regular old dict unpacking, and give a TypeError at runtime. -- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2QJGONYHLKTPDTLGIOATG4UJYEM4KBHG/ Code of Conduct: http://python.org/psf/codeofconduct/