develooper Front page | perl.perl5.porters | Postings from December 2016

[perl #130343] delete function error with ternary operator

From:
James E Keenan via RT
Date:
December 27, 2016 22:37
Subject:
[perl #130343] delete function error with ternary operator
Message ID:
rt-4.0.24-12976-1482878259-898.130343-15-0@perl.org
On Fri, 16 Dec 2016 07:24:43 GMT, demerphq wrote:
> On 15 December 2016 at 19:57, Brian Gomes Bascoy via RT
> <perlbug-followup@perl.org> wrote:
> > On Wed, 14 Dec 2016 15:26:48 -0800, zefram@fysh.org wrote:
> >> Brian Gomes Bascoy wrote:
> >> > It also says that EXPR can be "arbitrarily complicated provided
> >> > its final
> >> > operation is an element".
> >>
> >> That wording seems to have misled you.  The arbitrary complexity
> >> to which it refers lies in the subexpressions determining the hash
> >> and key; for example, "delete ${$a->()}{$b->()}" is entirely legal.
> >> It is not permitted to have any complexity in how the delete operand
> >> resolves to a hash element operation, as is the case in your
> >> example.
> >> What the documentation refers to as the "final operation" is really
> >> the *topmost* construct within the operand expression, not merely
> >> the
> >> last-executed operation.  We could improve that.
> >>
> >> > my %a = (a=>123, b=>321); my $n = 1; delete ($n ? $a{a} : $a{b});
> >> > # FAIL
> >>
> >> "delete $a{$n ? 'a' : 'b'}" would be legal.
> >>
> >> > Some folks on #perl @freenode mentioned that my first example only
> >> > works
> >> > because perl optimize the ternary operator,
> >>
> >> Yes.  The early constant folding of the conditional means that the
> >> compilation of the delete op only sees the hash element operation as
> >> its
> >> operand.  It doesn't realise that it was syntactically a
> >> conditional.
> >> This is arguably a bug, but also arguably not: that kind of
> >> behaviour
> >> can be deliberately invoked with respect to compile-time
> >> conditionals.
> >>
> >> -zefram
> >>
> >
> > I can totally see people using this kind of conditional compilation,
> > probably with constants instead of plain numeric literals. At the
> > same time I think that the optimization phase shouldn't change the
> > semantics of the code being interpreted. Using compile-time
> > conditionals as a sort of macro language is just a hack, not
> > something that it's part of the Perl language itself but just a
> > casual result of it's current implementation, or at least that's my
> > point of view :)
> >
> > Consider the following example:
> > my %a = (a=>123, b=>321); delete (foo==9 ? $a{a} : $a{b}); # ?
> >
> > That piece of code is ambiguous because foo was not defined. If foo
> > is a numeric constant (e.g. "use constant foo => 9;") that code
> > evaluates just fine. On the other hand, if foo is a subroutine that
> > returns a number (e.g. "sub foo { 9 }") it fails because it requires
> > run-time evaluation. IIRC constants are inlined subroutines so I can
> > see how someone could go from a constant foo to a more complex
> > subroutine foo.
> 
> FWIW, we used to have similar issues with ternaries and split,
> although IIRC it was a bit different. But the basic point remains,
> sometimes perl does things with expressions which don't work when the
> argument is a ternary.
> 
> Yves

Is this a problem about which, in the short run, we should write some cautionary documentation?

-- 
James E Keenan (jkeenan@cpan.org)

---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=130343



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About