On Monday, 5 August 2013 at 15:38:12 UTC, Dicebot wrote:
On Monday, 5 August 2013 at 15:30:45 UTC, Bosak wrote:
...

What you propose is rather unwelcome for classes (destruction of GC-managed objects is non-deterministic) and closest thing for IDisposable D has is "destroy" which is not something that is expected to be called silently.

However, I do like proposed extension of `with` syntax to allow declarations. It perfectly matches `if` and allows to emulate C# behavior via `scoped`. That will improve language consistency.

Oh yes using scoped to achieve that is a good solution. So if I write
with(File file = open("filename"))
{
    //setup file
    type = Types.Text; //etc.
}
string text = file.read(); //file still usable after with, but explicitly
And if I write the scoped version:
with(scoped!File file = open("filename"))
{
    //retrieve data from file or whatever
}
//file is out of scope and is not usable after

You say that D's destroy is not like C#'s IDisposable. Then why doesn't D then declare that kind of interface:
interface Disposable {
    void dispose();
}
And include it in the object module? That way some classes can implement this dispose method that will just dispose any used resources(and not to replace destructor's role). It is a very small(but core) change that is even not connected with the compiler, but only with phobos. For example std file structs can just implement the interface like this:
//...in File class/struct that implements Disposable
void dispose() {
    this.close();
}

And if you don't like the idea of adding an interface to the core module, then the same thing could be achieved if a special opDispose function is declared. This is a more D-way of doing it, since there exist opApply that is used only in the foreach construct and the opCall that is used to call classes like functions.

And then the with implementation is mostly straightforward. Depending on weather the declared variable is scoped or not, with behaves differently. If it is scoped it first checks if the object has dispose/opDispose method in it calls it and then destroys(or whatever the compiler does to scoped variables) it. And if it is not scoped then it doesn't dispose it and it acts just like with acts now(just the ability to declare the variable right in the with statement).

That way you explicitly specify that the variable is scoped and you know that it will be destroyed when it goes out of scope. In addition to that it dipposes "savely".

Maybe opDispose shouldn't be only used in with statement, but EVERYWHERE a scoped variable is declared? Here is a more complete example:

class Resource { //can be any resource from files to streams to anything
    Resource[] used;

    void opDispose() {
        writeln("Resource disposed!");
//in opDispose the resource should dispose all it's resources too
        foreach(res; used)
            res.opDispose();
    }

    static Resource open(string name){
        return new Resource;
    }
}

with(auto resource = Resource.open("res1")){
    //set properties of resource and call setup/init functions
}
resource.doStuff(); //use resource later too
resource.opDispose(); //you can manually dispose it

//or a scoped variant:
string[] data;
with(scoped!Resource res = Resource.open("res2")){
    data = res.getData();
}//res gets out of scope and opDispose is called

if(cond){
    scoped!Resource res = Resource.open("res3");
    //do sth with res
}//get out of scope opDispose gets called and res gets destroyed

I think this dispose thing should be added to D, because it is a very common practice in C#(and not only). In the book I used to learn C# long ago I remember how they sayed like 100 of times: "If you use an object that implements IDisposable ALLWAYS use it in an using statement". It is not a strange or not-intuitive feature. In fact it can make the "scoped" variables idea more popular. And instead of explicitly adding an using statement you just declare your variable as scoped and the compiler takes care of calling it's dispose automatically when it gets out of scope.

I think that's everything for now.

Reply via email to