develooper Front page | perl.perl5.porters | Postings from February 2023

Re: PERL_RC_STACK branch: first cut

Thread Previous | Thread Next
"Ruud H.G. van Tol" via perl5-porters
February 27, 2023 15:35
Re: PERL_RC_STACK branch: first cut
Message ID:

On 2023-02-27 14:12, demerphq wrote:
> On Mon, 27 Feb 2023 at 13:40, Ruud H.G. van Tol via perl5-porters 
> <> wrote:
>     On 2023-02-27 13:17, demerphq wrote:
>     > On Mon, 27 Feb 2023 at 12:45, Ruud H.G. van Tol via perl5-porters
>     > <> wrote:
>     >
>     >     I don't see (yet) how/why it should print out "foo".\
>     >
>     >     Why would you want/expect it to print "foo",
>     >     when you are using aliased parameters,
>     >     and are deliberately emptying the array?
>     >
>     >
>     > Because the scalar that holds "foo" has been pushed onto the stack
>     > independently of the array that originally contains it. The fact
>     that
>     > perl aliases arguments is a key part of this bug. If the stack was
>     > refcounted the alias would not be freed until the scalar was popped
>     > from the stack.
>     OK, so then it (partly) comes down to what one interprets (?) as
>     aliasing. 
>     I still think it was fine to print nothing (or to complain about
>     undefined).
> I don't understand why you would think that emptying out an array is 
> the same as undefing a scalar. They aren't the same thing at all.

By undef-ing, I meant that with Perl, using (as a value) something that 
has no backing, generally involves a stand-in undef.

perl -Mv5.28 -wE'my @x; say $x[42]'
Use of uninitialized value in say at -e line 1.

By default that warns, but doesn't die.

> Consider this code:
> perl -MArray::RefElem=av_push -le'my @a=("foo"); my @b; 
> av_push(@b,$a[0]); $a[0].="x"; @a=(); print $b[0]'
> foox
> I think we both agree this behaves correctly. (I hope). In this case 
> we are also storing an alias into @b, but it is properly refcounted. 
> So when we clear @a it does not free $a[0], as the scalar in $a[0] has 
> also been stored in @b.
> Here is an even closer analog:
> perl -MArray::RefElem=av_push -le'my @stack; my @a=(foo); av_push 
> @stack,\@a; av_push @stack, $a[0]; @{$stack[0]}=(); print $stack[1]'
> foo
> This example and the stack example from the earlier post are pretty 
> much functionally equivalent and should behave the same, and with 
> Dave's fix they do. Without it obviously they dont. Notice that 
> clearing @{$stack[0]} does not /free/ the scalar $a[0], because it 
> also stored in $stack[1], instead it merely evicts it from @a as part 
> of emptying @a. That is as expected because $stack[1] holds a refcount 
> on it. The bug that Dave is fixing is that the perl stack didnt do 
> that refcount increment, so the var would get freed prematurely.
> So unless you expect the two examples here to do something other than 
> what they do I think you have a flaw in your mental model about what 
> the original example was doing.  Which is not that surprising, this 
> bug has been around a long time and I imagine people are somewhat 
> habituated to it.

Right, the second parameter $a[0] (in the original, to me confusing, 
is not meant to act as "a lazy getter" (though overload could make it do 
but should be an independent scalar, by itself, with a clear state.

I preferred it to print empty/undef, because the example is using the 
But indeed in this context it is more reasonable to solve the list 
before starting the sub.

Still those are implementation choices.

Example of "eager list" vs. "lazy list":

perl -Mv5.28 -wE'
   $a= 0;
   my @a= (++$a, ++$a, ++$a);
   say "@a";

   $b= 1;
   my @b= ($b++, $b++, $b++);
   say "@b";
3 3 3
1 2 3

-- Ruud

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About