develooper Front page | perl.perl5.porters | Postings from April 2008

Re: Make built-in list functions continuous

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
April 6, 2008 04:27
Subject:
Re: Make built-in list functions continuous
Message ID:
20080406112726.GI79799@plum.flirble.org
On Tue, Apr 01, 2008 at 09:45:30AM -0500, Graham Barr wrote:
> On Apr 1, 2008, at 8:49 AM, Nicholas Clark wrote:

> >>There's also a related optimization which takes the composition of  
> >>maps
> >>as the map of composition. I.e. these two lines are equivalent,  
> >>but the
> >>latter is more efficient:
> >>
> >>    @xs = map {f($_)} map {g($_)} @ys;

> >(which at least avoids needing a full length temporary list, and  
> >would combine
> >with your previous re-write to become
> >
> >     my @xs;
> >     foreach my $y (@ys) {
> >	push @xs, f($_) foreach g($y);
> >     }
> 
> That is probably the best you can do to save memory

But following some more thinking and a conversation with Dave Mitchell, even
this can't be done in the general case of

    @xs = map {f($_)} map {g($_)} @ys;

It fails

1: if f() or g() are accessing @xs, because they expect @xs to have its
   original contents

2: if f() or g() throw an exception part way through, because then @xs ends up
   partly changed, rather than still holding the old contents.


I think that the only general case where it is applicable is where it's for
the declaration and assignment of a new lexical in one statement, or inside
an anonymous array constructor, because in either, there's no possibility of
referencing the array being modified, or holding onto a reference to it that
could escape outside an eval block.

Nicholas Clark

Thread Previous | 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