http://qs321.pair.com?node_id=193496


in reply to On timely destruction?

Thanks for asking. I'm a zelot on timely destruction, and have been meaning to lobby for not dropping it in Perl 6!

If there is a performance issue, at least make it optional. Objects that need it can have DESTROY called when the last reference is dropped, even if others wait for a central garbage collection scheme or have the code moved outward a few more blocks.

If allocation failure of X for any X triggers a sweep, that's great and addresses the "not everything is memory" issue.

But, here is an example: file is still open so nobody else can open it until it's cleaned up, as opposed to running out of file handles (not going to happen in Windows).

How about a window on the screen? I drop the object and the window doesn't go away until the gc gets around to it! Sure, I can code the close() call myself at the end of the block (and wish I still had real destructors), but that does not work in the face of exceptions. Don't make me put this in a finally block every time; the class should know that and take care of itself.

How about any code that has a "before" and "after" stage, with my code in between. A semaphore is a good example. Building the "after" semantics into the object with language support is a useful tool. The idea of "resource acquisition is initialization" is powerful, and heavily used by C++ programmers. With Perl6 poised to take over the world, don't annoy your potential users like Java did by removing features that they rely on in their other languages.

Ideas: Some classes can be declared with a "needs timely destruction" property. If at least one of these is in a scope, then a gc sweep will be triggered at the end (or finally clause) of that block.

Or, the proper call can be added to the block's finally clause implicitly (Larry showed an explicit way to note this as a property on the declaration of the variable. take that one step further).

Putting in a close() myself or implicitly is going to do it most of the time, but will break down for closures. The compiler can count references; let it do that work for me. But again, the compiler can know when this is never going to happen and emit the simple code. How much of that is part of the low-level Parrot assembly code vs. smarts in the compiler? I think if the compiler could emit code that says "exit scope; if referece count of the variable reached zero, then call function" then it can take it from there.

—John

Replies are listed 'Best First'.
Re: On timely destruction?
by sfink (Deacon) on Aug 28, 2002 at 20:30 UTC
    More precisely, you're arguing for timely finalization, not destruction. The time of destruction usually isn't relevant.

    Making it optional may not help the implementation difficulties much. Any object requiring prompt finalization may be pointed to by something buried deep within a graph of objects that don't care, so you still have to check for the final reference being lost even when you're only manipulating objects that don't care.

    Your locked open file example is a good one, I think, although I wonder how many times it could be handled with a scope exit action (how often will you pass it to some routine that could keep a global handle on it? If you're doing that, then you're probably not too concerned with the locking issue...)

    The window example can certainly be handled with a scope exit mechanism -- you wouldn't be coding the cleanup down at the bottom of the block, you'd be inserting it into a CLEANUP{} block or something that the compiler would be required to call no matter how the block is exited.

    Your gc sweep at the end of a block idea works, except for the case when the variable escapes the block (eg it's referenced by a global cache.) Then you'd need to remember that there is at least one rogue object that requires timely finalization floating around, and you'd have to trigger a sweep at every scope exit. Or worse, if you really want it immediate -- simple variable assignment drops a reference to the previous contents, so perl5 can trigger DESTROY even then. A sweep after every assignment might be a little slow...

Re: Re: On timely destruction?
by Elian (Parson) on Aug 29, 2002 at 06:48 UTC
    Thanks for asking. I'm a zelot on timely destruction, and have been meaning to lobby for not dropping it in Perl 6!
    Cool, then. Give me examples of things that'll break without timely finalization!
    If there is a performance issue, at least make it optional.
    Ah, therein lies the rub. You can't make something like this optional. It's either there, with full support for it, or it's not there. There is no optional here. (If there was, I'd not be asking this question)

    Unfortunately none of the things you've presented quite do it. Filehandles will be cleaned up reasonably quickly. Windows definitely ought not go missing without some active action on the part of a program. And "after" semantics on objects when they get destroyed, well, you get that. It's just potentially indeterminate when it happens. (Which, I realize, is the issue)

    I think if the compiler could emit code that says "exit scope; if referece count of the variable reached zero, then call function" then it can take it from there.
    There are no reference counts in parrot, and thus none in perl 6. If there were this wouldn't be an issue.