1. "Protect/handle", a.k.a. "make it look like try/catch": this version
pursues the arrangement with protected-code coming first and handlers
coming second. To do this, the protected-code has to be suspended in a
closure, which is then passed to a temporary struct, which is
responsible for both capturing the remaining handler-part and firing the
push/run/pop cycle together at the end. Uses of it look like this:

   let b = do OutOfKittens.protect {
       do_some_stuff();
       that_might_raise();
       out_of_kittens();
   };

   do b.handle |t| {
       UseAardvarksInstead
   }

It's not really an ideal use of our 'do' syntax, nor are many other
variants of this API I've tried. It might read slightly better (or
worse) as such:

   (do OutOfKittens.protect {
       do_some_stuff();
       that_might_raise();
       out_of_kittens();
   }).handle(|t|
       UseAardvarksInstead
   );

This is my preferred arrangement, though without the parens. The primary reason is because I always prefer the exceptional flow to come last.

I could also imagine something like:

do protect {
    ...
}.handle::<OutOfKittens>(|ex|
).handle::<OutOfMilk>(|ex|
);



2. "Guard", a.k.a. "make it look like RAII": this version has only a
single "floating in space" handler-block that is assigned to a temporary
guard object in the current scope, and all subsequent code in that scope
is protected. Reads like this:

   {
       let _g = OutOfKittens.guard(|t| UseAardvarksInstead);
       do_some_stuff();
       that_might_raise();
       out_of_kittens();
   }

Downsides of this mechanism are that a user might try to move _g out of
the current frame or otherwise tamper with it -- we might need to do
some tricks with the region system to prevent that -- and it gives rise
to this somewhat artificial _g variable and otherwise unclear extra
block to contain it.

3. "Trap/in", a.k.a. "the system I like the look of best": this is the
version Patrick suggested yesterday. It sets up the handlers in the head
of a do-block and then invokes the protected code. It's order-inverted
from protect/handle -- the handlers come before the protected code --
but it still reads ok to my eyes, and seems to play nicely with our
existing syntax:

   do OutOfKittens.trap(|t| UseAardvarksInstead).in {
       do_some_stuff();
       that_might_raise();
       out_of_kittens();
   }


_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to