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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/2QJGONYHLKTPDTLGIOATG4UJYEM4KBHG/
Code of Conduct: http://python.org/psf/codeofconduct/