Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Does Perl have known memory leaks?
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Larry Wall  
View profile  
 More options Nov 14 1991, 4:03 am
Newsgroups: comp.lang.perl
From: lw...@netlabs.com (Larry Wall)
Date: 13 Nov 91 19:44:20 GMT
Local: Wed, Nov 13 1991 2:44 pm
Subject: Re: Does Perl have known memory leaks?
In article <8i1H!0...@cs.psu.edu> f...@cs.psu.edu (Felix Lee) writes:

: Re: local() statement inside a block,
:
: Okay.  Here's a different explanation.  A 'block' is a dynamic object
: that takes considerable effort to create.  If a loop were to create
: and destroy a block on every iteration, it would be much, much slower,
: so instead, loops create their block just once and repeatedly execute
: it.  (This is not really any different from how other languages treat
: blocks, except many languages have static block objects instead.)

This is essentially correct.  I guess that's part of why you don't see
more interpreters for declarative-rich languages...

But my usage of terms will certainly seem perverse to those steeped in
compiler technology.  And I do mis-speak myself.  The book shouldn't
have said that local() "declares" anything.

As for the term "block", I only called it that because of it's
resemblance to the blocks of a compiled language.  However, in Perl,
the only bit of static scoping tied to blocks is the package
declaration.  (There is no scoping for subroutines or formats.)  All
other scoping happens at runtime, in whichever way I deem to be most
useful and efficient.  There's a heap of stuff internal to the
interpreter that gets localized just like your local variables, and
it's all dynamic.  It almost has to be, if you want the compiler to run
in under 53 megabytes.

: Now this loop optimization interacts poorly with the fact that 'local'
: is an executable statement, not a declaration.  In nearly every other
: language, the equivalent to local is a declaration, so it happens just
: once, when the block is created.  But in perl, the local happens every
: time the block is executed.
:
: This is merely a flaw in implementation.  It makes no difference to
: the meaning of the program whether a local() in a loop consumes
: megabytes of memory or not.

True, but there is a semantic distinction here too, quite aside from
the quibble about vocabulary.  In the current setup

        for (1..10) {
            $huh = $foo;
            local($foo);
            ...
        }

sets $huh to the current local value of $foo.  It only gets the global value
of $foo on the first time through the loop.  If we made $foo revert
to the global value at the end of each iteration, $huh gets the global
value each time.

: One way to fix this is to turn local into a declaration, but this may
: break code like this:
:       $x = 'local($y)';
:       { eval $x; $y = 3; }
: Does this matter?  Perhaps not.

Actually, the example above is ok, since local() is local to an eval too.
But it would definitely break things like

        local($_) = $_[0] if @_;

: Another way to fix this is to note which block local variables belong
: to.  If you execute another local for the same variable in the same
: block, you can reclaim the old version since it will never be
: accessible again.  Or, equivalently, you could make the local a noop
: and just reuse the same slot.

But you have to be very careful about recursion.  You don't want

        sub FOO {
            local($BAR);
            ...
            &FOO;
        }

to break.  Nevertheless, it would be a good way to fix it if we want to
keep the current semantics.  If we want local() to revert at the
end of the block, however, it won't fly.

Making it revert at the end of the block would certainly impose more
time overhead (and less space overhead, which is what started this all
off in the first place) on those scripts that do local() within a loop
block.  It would probably also impose more overhead on scripts that don't
do local().

One thing that complicates matters is that the interpreter DOESN'T
actually exit the block on each loop iteration.  A loop like

        while ($cond) {
            &stuff;
        }

is optimized to something resembling

        if ($cond) {
            TOP:
                &stuff;
                last unless $cond;
                goto TOP;
        }

except that the if isn't really an if and the goto isn't really a goto.
The inner block is really a circular linked list of statements, so it
looks to the interpreter like

        &stuff;
        last unless $cond;
        &stuff;
        last unless $cond;
        &stuff;
        last unless $cond;
        &stuff;
        last unless $cond;
        &stuff;
        last unless $cond;
        ...

In order to make local() revert, I'd have to stick something in to
check if anything needs to revert, and that might slow things down
even when nothing needs to revert.  Yes, compile-time analysis might
determine whether such a check was even necessary, but Perl already
does about 2 1/2 passes, and I already get enough complaints about
startup time.

We all agree on the necessity of compromise.  We just can't agree on
when it's necessary to compromise.

Larry


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.