On Tue, May 25, 2021 at 10:10:12PM +1000, Chris Angelico wrote: > On Tue, May 25, 2021 at 5:29 PM Steven D'Aprano <st...@pearwood.info> wrote: > > Here's a counter-proposal: we have a special symbol which is transformed > > at compile-time to the left hand assignment target as a string. Let's > > say we make that special expression `@@` or the googly-eyes symbol.
[...] > > Targets aren't limited to a single bare name. > > > > spam.eggs = @@ > > # spam.eggs = 'spam.eggs' > > > > mylist[2] = @@ > > # mylist[2] = 'mylist[2]' > > What about: > > mylist[ 2 ] = @@ > > ? I'm inclined to say that the assignment target is reconstructed from > the AST, in order to make it consistent (so this would also assign the > string 'mylist[2]'). But, again, bikesheddable. Let the implementation decide whether it is easier to get the target from the source code or the AST. I don't care either way. > > If the key or index is not known at compile-time, it is a syntax error: > > > > mylist[getindex()] = @@ # SyntaxError > > Also bikesheddable; I'd actually say that this should assign the > string 'mylist[getindex()]', regardless of the value returned by > getindex. My reasoning it that it is safer and more conservative to start with a restriction and relax it later, than to start with a less restrictive version and regret it. But I could be persuaded otherwise :-) > > Chained assignments transform to a tuple of target names: > > > > spam = eggs = cheese = func(arg, @@) > > # spam = eggs = cheese = func(arg, ('spam', 'eggs', 'cheese')) > > Hmm. Everything else gives you a single string, this one doesn't. I'd > actually be inclined to switch around this one and the next one... A complication I just thought of is that you can have chained assignment within a sequence unpacking assignment: spam, eggs, aardvark = foo = bar, hovercraft = 'abcd' and the other way around: spam = eggs = (aardvark, foo, bar) = hovercraft = 'abc' That's going to make things tricky. > > Sequence unpacking assignment gets transformed as a single > > comma-seperated string: > > > > spam.eggs, foo, *bar = func(arg, @@) > > # spam.eggs, foo, *bar = func(arg, ('spam.eggs,foo,*bar')) > > ... so that assigning the same thing to multiple names gives you a > space-separated string (or equals-separated, "spam=eggs=cheese"), but > unpacking gives you a tuple of targets, since it then nicely parallels > the result it's expecting from the function. That would mean that: > > # This assigns a single string to them all eg "spam eggs cheese" > spam = eggs = cheese = @@ > # This assigns a string to each one: > spam, eggs, cheese = @@ > # and is equivalent to: > spam = @@; eggs = @@; cheese = @@ I have to think about that some more :-) > This has the same sort of value as the C preprocessor stringification > operator. It's incredibly handy in making self-referential statements. Nice analogy. > Python has places where that happens by magic (class and function > definitions), but if you want to create your own function that gets > the same benefit.... well.... there's __set_name__ if your thing gets > put into a class, but otherwise you have to repeat the name. Yes. > Questions: > > 1) Is this restricted to the "=" assignment operator, or will other > operators trigger this too? > x += f(@@) # ? > if x := f(@@): # ? I hadn't thought that far ahead. I did think that we ought to exclude the walrus operator because it would be ambiguous: spam = eggs * (cheese:=foo+bar(@@)) Does @@ get the value 'cheese' or 'spam'? If we require an assignment statement, then it can only be 'spam' and the ambiguity is gone. > 2) What about other forms of assignment? > for spam in foo(@@): # ? YAGNI. We can always extend the functionality later. Let's keep it simple: it works for assignment statements, not every binding operation. > 3) Is this a string literal, or a magic token that happens to evaluate > as a string? An actual string. > x = @@ ".json" # Legal if @@ is a string literal Heh, I wouldn't necessarily require that. (Nor would I object to it.) Implicit string concatenation is a nice feature, but I'm not sure we want to extend it. Its not hard to slot an explicit `+` in there. -- Steve _______________________________________________ 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/73K5XH66TWPI4KTKYJPE2IHQXE3RUCFL/ Code of Conduct: http://python.org/psf/codeofconduct/