Prototype of Ownership/Borrowing System for D

mipri mipri at minimaltype.com
Thu Nov 21 21:49:57 UTC 2019


On Wednesday, 20 November 2019 at 04:59:37 UTC, Walter Bright 
wrote:
> https://github.com/dlang/dmd/pull/10586
>
> 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));
           f(&lf);
       }

       void close() { // [3]
           file.close();
       }
   }

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

   void live_close(LinearFile* f) {
       f.close;
   }

   void main() {
       import std.stdio: write;

       LinearFile.open("/etc/passwd", delegate(f) @live {
           write(f.readln);
           //f.close; // not an error to omit this [2]
       });

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

       void better(LinearFile* f) @live { // [4]
           write(f.readln);
           destroy(f); // error to omit this
           // write(f.readln); // error to use f after destroy
       }
       LinearFile.open("/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 
@live.

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