On Sat, Oct 20, 2012 at 5:31 AM, Matthieu Monrocq
<[email protected]> wrote:
>
>
> On Sat, Oct 20, 2012 at 1:37 PM, Gareth Smith <[email protected]>
> wrote:
>>
>> Option 3 looks prettiest to me, but I like that in Option 1 the
>> error-raising code comes before the error-handling code (based on experience
>> with other languages). This might not be an issue in practice.
>>
>> I am not sure how I like Option 3 with a more complex trap block:
>>
>>   OutOfKittens.trap(|t| {
>>       OrderFailure.trap(|t| notify_support()).in {
>>           order_more_kittens();
>>       }
>>       UseAardvarksInstead
>>   }).in {
>>       do_some_stuff();
>>       that_might_raise();
>>       out_of_kittens();
>>   }
>>
>> Compare this to some "ideal" syntax:
>>
>>   protect {
>>       do_some_stuff();
>>       that_might_raise();
>>       out_of_kittens();
>>   } handle OutOfKittens(t) {
>>       protect {
>>           order_more_kittens();
>>       } handle OrderFailure(t) {
>>           notify_support();
>>       }
>>       UseAardvarksInstead
>>   )
>>
>> Gareth
>>
>> _______________________________________________
>> Rust-dev mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/rust-dev
>
>
> I just realized I had missed a point, which is somewhat similar to what
> Gareth raised: composability.
>
> Let us start with an example in a C++ like language:
>
>     UserPreferences loadUserPreferences(std::string const& username) {
>         try {
>             return loadUserPreferencesFromJson(username);
>         } catch(FileNotFound const&) {
>             if (username == "toto") { throw; }
>             return loadUserPreferencesFromXml(username); // not so long ago
> we used xml
>         }
>     }
>
> The one thing here is "throw;", which rethrows the current exception and
> pass it up the handler chain.
>
> Is there any plan to have this available in this Condition/Signal scheme ?
> Ie, being able in a condition to defer the decision to the previous handler
> that was setup for the very same condition ?
>

I might not understand TPS well, but it sounds like a user could
implement this "stack" using closures, even if the condition library
did not provide it:

// Excuse my poor imitation rust:

fn loadUserPreferences( username : ~str ) : UserPreferences {

  let outerHandler = TPS::read( &FileNotFoundCondition );
  // Note: I assume a TPS::read function, but I'm not sure if it fits
with TPS design.

  // Now pretend the #3 "trap" style API:

  do FileNotFoundCondition.trap(
      |t| if (username == "toto") then outerHandler(t) else
loadUserPreferencesFromXml( username ))
    ).in {
      return loadUserPreferencesFromJson( username );
    }
  };
}

Is this feasible?  If not, what have I missed?


> It could be as simple as a    core::condition::signal(OutOfKittens, t)
> from within the current handler block. Which basically means that during its
> invocation the current handler is temporarily "popped" from the stack of
> handlers (for that condition) and after its executes (if it does not fail)
> is pushed back.
>
> I even wonder if this could not become "automatic", that is unless a handler
> "fails" hard or returns a proper value, its "predecessor" is automatically
> called. However I failed to see how this could be nicely integrated in the
> syntax and wonder what the ratio of "pass-up-the-chain" vs
> "ignore-predecessors" would be in practice.
>
> -- Matthieu
>
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
>


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

Reply via email to