Prototype of Ownership/Borrowing System for D

mipri mipri at
Thu Nov 21 21:49:57 UTC 2019

On Wednesday, 20 November 2019 at 04:59:37 UTC, Walter Bright 
> It's entirely opt-in by adding the `@live` attribute on a 
> function, and the implementation is pretty much contained in 
> one module, so it doesn't disrupt the rest of the compiler.

Here's a thing:

   struct LinearFile {
       import std.stdio: File;
       protected File file;

       // [1]
       static void open(string name, void delegate(LinearFile*) 
@live f) {
           auto lf = LinearFile(File(name));

       void close() { // [3]

   string readln(scope LinearFile* f) {
       return f.file.readln;

   void live_close(LinearFile* f) {

   void main() {
       import std.stdio: write;"/etc/passwd", delegate(f) @live {
           //f.close; // not an error to omit this [2]

       void firstline(LinearFile* f) @live {
           // f.close; // still dangling after this
       }"/etc/passwd", &firstline);

       void better(LinearFile* f) @live { // [4]
           destroy(f); // error to omit this
           // write(f.readln); // error to use f after destroy
       }"/etc/passwd", &better);

The idea of course is to have a resource that's statically
guaranteed to be cleaned up, by giving the caller a @live
requirement to not leave a pointer dangling, and no
non-borrowing function to pass the pointer to, except for the
clean-up function.

With references:

1. I don't know how (or if it's possible to) require callers to be
@live though, so instead I require that a passed delegate be 

2. @live doesn't seem to work with anonymous delegates though, as
the f.close isn't required here.

3. methods also seem to be non-borrowing, so the LinearFile.close
method is a bug. Which isn't convenient for imports at least:

   import linear: LinearThing, close;

4. ...and it was only when I started to add that it was a shame
that you can't just use destructors, that I thought to try them.

More information about the Digitalmars-d mailing list