In which Tigger maintains that code relying on timely destruction in
perl5 is buggy [and relatively rare], and agrees wholeheartedly with
Rabbit on almost everything else.
On Fri, 2005-01-14 at 17:52 -0700, Luke Palmer wrote:
> Shevek writes:
> > The example you described destroyed a ref within a sub, and then assumed
> > that the object refed would be destroyed at scope exit.
>
> I'm assuming you're referring to my Perl example, which you tactfully
> omitted in order to lose the casual reader. Very cunning. :-)
My mistake, I was too heavy with [del]. I meant to put it back in.
> Here it is again:
>
> my %data;
> sub a {
> open my $fh, "> somefile";
> $data{fh} = $fh;
> }
> sub b {
> %data = ();
# $fh is destroyed here, not at scope exit
foo();
bar();
# not here.
> }
> a();
> # ...
> b();
>
> And what I mean is that most approximate solutions won't destroy $fh in
> time. One example of such a proposal is keeping tabs on objects in the
Timely destruction in C++ (I think the only language we have mentioned
which _officially_ implements it) only happens at scope exit. "Timely
destruction" in Perl5 happens (probably) kind of when the ref goes away,
although I don't think even that is guaranteed, my memory of temporaries
and targets is too fuzzy.
> current scope which need timely destruction and then do a sweep whenever
> we lose a reference to one. Another is using generational schemes.
> Generational schemes are good for finding *enough* dead objects quickly
> when we run out of memory, but they're not good for finding whether a
> particular object is dead.
But they may be adequate in a pinch for handling many simple cases of
timely destruction. However we are likely to dig the same hole as perl5
where programmers rely on the behaviour [see bottom].
> However, Perl 5, since it uses refcounting everywhere, has no problem
> with this. Parrot has decided not to use refcounting at all (a decision
> that I think I agree with), and so we have this problem.
>
> > This is incorrect: the object refed should be destroyed when the ref is
> > destroyed in a general refcounting GC system.
>
> And I don't understand what you mean here.
The example above demonstrates.
> > Anyway, this led me to the (useful?) thought that you could delink the
> > concept of timely GC and destruction at scope exit by registering
> > atexit() or atleave() code on a scope (like finally{}) which explicitly
> > undef'd registered PMCs. That way you would be able to guarantee
> > destruction even if the PMC was still ref'd, which is probably more use
> > for things like critical section locks than just relying on a
> > side-effect of the GC, and is certainly easier to implement since it's
> > just a flag on the lexical in the pad.
>
> Precisely! But if we have to support this area of Perl 5 (I'm not
> certain that we do yet), we have to implement its semantics
> backward-compatibly. The programmer of Perl 5 relied on the side
> effects because they worked then. So we're not allowed to break them.
I maintain that relying on those semantics is a clear violation of the
documentation, as explicitly stated somewhere I can't immediately find,
but someone else must be able to find the passage. Such code may be
considered broken. I also suspect it's not a hugely common case.
> And because of Perl 6's many lexical scope hooks, I hope that we can get
> rid of any timely destruction policy, to encourage the use of lexical
> hooks instead of destruction rules.
Yes. Lexical hooks good.
> No matter how we slice it, it would royally suck to add a sweep at the
> end of every lexical scope.
I wouldn't worry too much about a last-generation sweep at that point,
especially if we know which zones are in scope (as opposed to extent) at
that time. However, I doubt anyone is going to implement this.
S.