develooper Front page | perl.perl5.porters | Postings from June 2013

[perl #109744] referenced constant loses readonlyness

Thread Next
From:
Father Chrysostomos via RT
Date:
June 11, 2013 01:14
Subject:
[perl #109744] referenced constant loses readonlyness
Message ID:
rt-3.6.HEAD-2552-1370913240-1371.109744-15-0@perl.org
On Tue Jul 03 13:18:19 2012, sprout wrote:
> On Tue Jul 03 11:19:55 2012, doy wrote:
> > Is this the same issue as #21979?
> 
> Pretty much.  But fixing it is not as simple as ‘fixing’ it.
> 
> "$a$b" returns a new value each time, so there is no reason for it to be
> read-only.  Some would argue that "a" and 1..3 should return modifiable
> values, since there’s no harm in that.  But other want referential
> identity to be preserved.
> 
> In the case of built-in operators (even const ops), I lean toward the
> side of modifiability, though I know that referential identity is
> important in many cases, too.
> 
> It’s hard to solve, really.  How should constants behave?  If a constant
> is just a subroutine,  then foo() should behave like a subroutine and
> return a modifiable value (unless it has the :lvalue attribute).  But
> constants produced by ‘use constant’ are often used to inline literally
> the same value.

OK, so there are three arguments regarding whether values return by
potentially constant operators should be modifiable:

1) It doesn’t cause any harm to make it modifiable, so why not? It’s
Perlish.
2) I was expecting it not to be modifiable, so that it is modifiable
must be a bug.
3) I need this thing to return exactly the same scalar, so I can compare
memory addresses.

I’m afraid the second one sounds stupid because I am biased against it
and know not how to express it convincingly.  I have seen a similar
argument come up in bug reports, which stated what was expected, but not
why.  I don’t find it convincing at all.

That leaves us with 1 and 3.  I propose that we make threaded and
non-threaded perls the same, like this (a compromise between the two
current sets of behaviour, with a twist):

• Operators that return different values depending on parameters ($a+$b,
"$a$b") should continue to return modifiable values.  This will include
1..3, since the values returned are scalars generated on the fly.
• For consistency (constant folding is just an optimisation, and should
not change behaviour), this will be extended to foldable operations, too
(1+2, "a"."b"), which were modifiable only under threads.
• Other literal strings and numbers will be read-only, even when passed
to subroutines.  Currently under threads, it’s a bit of both, and the
implementation details leak like a sieve.
• Return values of ! and other operators returning booleans will
continue to be read-only, as they are not generated scalars, but two
specific scalars, &PL_sv_yes and &PL_sv_no.
• Inlined constant subs created by ‘use constant’ and ‘sub (){42}’ will
be *modifiable*, because sub calls copy their return values.  In other
words, these two will behave the same way:

    for ( sub(){       42}->() ) { $_++ }
    for ( sub(){return 42}->() ) { $_++ }

Furthermore, ‘use constant’ usually copies the values anyway.
• Referential identity will still be preserved by XS modules that make
their own const ops.  Whether the value is read-only will depend on
whether the module makes it read-only.

I’m going to go head and work on this.  You’d better yell loudly if you
disagree. :-)

-- 

Father Chrysostomos


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

Thread Next


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