daokoder / dao

Dao Programming Language
http://daoscript.org
Other
199 stars 19 forks source link

Possible to define uncallable routines #380

Open ShadauxCat opened 9 years ago

ShadauxCat commented 9 years ago

Playing around seeing if I could figure out whether or not Dao has destructors, I made a class that looks like this:

class MyClass
{
    routine MyClass()
    {
        io.writeln("Construct");
    }

    routine ~MyClass()
    {
        io.writeln("Destruct");
    }
}

This works completely fine! Obviously since this does not seem to be the way to define destructors, it doesn't seem to do anything, but it doesn't throw an error.

Until I do this:

var mc : MyClass = MyClass();
mc.~MyClass();

Then it throws a fit.

This is really kind of a minor issue, but as a polish item, it seems like this is something the compiler should throw an error about at the time an invalid method is defined rather than when it's called.

ShadauxCat commented 9 years ago

I didn't respond promptly because I really didn't have sufficient time (for the reasons I mentioned in one of my previous posts).

Totally get that. Given the timing of my posts, I figured you were off on Chinese New Year activities. Didn't realize you were looking for a job, though; good luck on your job search.

daokoder commented 9 years ago

When to destructors get called for native types? Are they called at predictable times (i.e., when ref count reaches 0) or are they called whenever the GC gets to them?

When the external ref count reaches zero, namely when the object or a group of objects have no ref count from outside of the group. It is predictable in the sense that they will be called within 2 GC cycles after the external ref count reaches zero. But it is not precisely predictable, because the time of each GC cycle is unpredictable.

good luck on your job search.

Thanks, but I already found two :)

ShadauxCat commented 9 years ago

Is there any reason they're not called immediately upon the ref count reaching zero? Even if the memory's not cleaned up yet, destructors would be much more reliable if they were called at that exact moment when ref count reaches 0.

Night-walker commented 9 years ago

BTW, I got my current job solely due to the knowledge and skills acquired during my work on Dao. It's curious how a spontaneous free-time hobby may eventually form your professional background. Even change your life.

ShadauxCat commented 9 years ago

@Night-walker - Absolutely. I got my first game job due to work I did on a MUD.

Night-walker commented 9 years ago

Back to destructors. I actually also had ideas about using wrapped type as a proxy to implement Dao-level destructors. It's nice as you can easily distinguish classes which have destructors from those which haven't.

But I'm not sure what thread (DaoProcess) will execute that routine. Currently destructors of wrapped types seem to be carried out by the GC in its own thread, without a DaoProcess. Unless desctructor is actually called from the DaoProcess which releases the last references to particular object, most problems I mentioned earlier still stay.

ShadauxCat commented 9 years ago

But I'm not sure what thread (DaoProcess) will execute that routine. Currently destructors of wrapped types seem to be carried out by the GC in its own thread, without a DaoProcess. Unless desctructor is actually called from the DaoProcess which releases the last references to particular object, most problems I mentioned earlier still stay.

I agree. Destructors will be most useful if they are called immediately when the last reference disappears, on both the same DaoProcess and the same thread. Reliable destructors that are called at predictable times are very useful. Unreliable finalizers that are called whenever the GC happens to run, far less so.

There will still be the problem of what happens if an object revives itself; I think that should just be caught and result in an error. I don't think Dao should allow objects to be revived once they've started getting destroyed.

Night-walker commented 9 years ago

There will still be the problem of what happens if an object revives itself; I think that should just be caught and result in an error. I don't think Dao should allow objects to be revived once they've started getting destroyed.

I don't think it can be detected trivially, not to mention the context in which the error should be raised. The main thing which can be done here reliably, I guess, is de-registering the destructor so it won't run repeatedly.

ShadauxCat commented 9 years ago

I don't think it can be detected trivially, not to mention the context in which the error should be raised. The main thing which can be done here reliably, I guess, is de-registering the destructor so it won't run repeatedly.

It wouldn't be difficult to detect. The object gets a simple flag to say whether or not it's currently destructing. Before the destructor is called, that flag gets set. If DaoGC_IncRC() is called on an object with that flag set, it throws an error.

Night-walker commented 9 years ago

It wouldn't be difficult to detect. The object gets a simple flag to say whether or not it's currently destructing. Before the destructor is called, that flag gets set. If DaoGC_IncRC() is called on an object with that flag set, it throws an error.

It's not that simple. If you simply prohibit adjustment of reference counter on self, methods or functions taking self as parameter will become inaccessible, which limits the use of destructors.

daokoder commented 9 years ago

Is there any reason they're not called immediately upon the ref count reaching zero? Even if the memory's not cleaned up yet, destructors would be much more reliable if they were called at that exact moment when ref count reaches 0.

Dao class instance objects are always cyclically referenced, because each object has a reference to its "root" object for possible down casting and a reference to its possible parent object. So they can only be detected to be garbage by GC. Even though this can be changed, calling destructors at arbitrary thread and arbitrary site is very problematic.

daokoder commented 9 years ago

BTW, I got my current job solely due to the knowledge and skills acquired during my work on Dao. It's curious how a spontaneous free-time hobby may eventually form your professional background. Even change your life.

Nice to know that:-). It would also be the case for me if I decide to take the job that is directly related to programming language and compiler.

daokoder commented 9 years ago

But I'm not sure what thread (DaoProcess) will execute that routine. Currently destructors of wrapped types seem to be carried out by the GC in its own thread, without a DaoProcess.

Such routines will be executed in the GC thread, it can acquire a unique DaoProcess object for that.

Night-walker commented 9 years ago

Such routines will be executed in the GC thread, it can acquire a unique DaoProcess object for that.

Problem No 1: destructor may hang indefinitely, effectively freezing the GC.