Front page | perl.perl5.porters |
Postings from June 2021
Re: PSC #024 2021-06-11
From: Ricardo Signes
June 15, 2021 18:22
Re: PSC #024 2021-06-11
Message ID: email@example.com
On Sun, Jun 13, 2021, at 9:43 PM, Tony Cook wrote:
> On Sun, Jun 13, 2021 at 10:01:33AM +0100, Neil Bowers wrote:
> > Assignment to undef, and a quirk
> > Tony C submitted a PR on 2021-06-02 which changes the behaviour on
> assigning to undef within a ternary. We discussed whether
> assigning should be legal in any context. But we then ended up
> looking at what was really going on with ($x ? $y : undef). Rik
> started dumping out op trees for different examples, and bouncing
> back & forth with Nick on what was going on. Oh how naive I was,
> thinking the previous topic went on for a long time. Rik is going to
> email a summary of this, with a suggestion for what might change.
> It's a bit strange.
So, Tony's email covered quite a bit of what I said I'd summarize, but I'll try to hit the points we had talked about.
$x = foo(); # scalar context
($x) = foo(); # list context
$x, $y = foo(); # scalar context, but clearly a bug; = is tighter than ,
($x, $y) = foo(); # list context
$x ? $t : $f = foo(); # scalar context
($x ? $t : $f, $z) = foo(); # list context; (remember that ?: bind tighter than ,)
($x ? $t : $f) = foo(); # scalar context
($x ? $s : @a) = foo(); # ambiguous! a warning is issued
It is easy to read this and think the following thoughts:
* to turn a scalar assignment into a list
* except if that expression is a ternary alone inside the parens, where the compiler optimizes us into scalar assignment
* if the compiler can decide to shift between AASSIGN and SASSIGN as an optimization, they must have equivalent semantics for assignment to the literal undef
This is sort of where we ended up, feeling confused, on our last PSC call.
The reality of the situation, as Tony pointed out in his email, and as Matthew Horsfall pointed out to me in a chat, is that merely having "an expression in parens" on the left hand side is not sufficient to create list context. As Tony showed, you need to write something like:
$x ? ($t) : ($f) = foo();
This isn't the same thing as "the compiler optimized". It's a question, I think, of how the language is meant to work. The problem is that it leave me thinking, "I don't really know what the clear rule is for 'is this assignment going to be in list context'". This is not a situation I like to be in!
Tony suggests making ($x ? $y : $z) become a list assignment target, but this strikes me as pretty risky, for two reasons: First off, it's going to change the calling context of some yet-uncounted number of assignments. Secondly, clearly a few people immediately said, "No, assigning to a ternary in parens does not create list context", so they already understand. I don't get to declare my expectations correct just because somebody put a sticker next to my name.
I'm not sure I really have a great suggestion, here, except for this one: We should make sure that there is a clear explanation of how that context decision is made, and then somebody should point me at it so I can read it. 😐