On 04/27/2013 03:30 PM, Vicente J. Botet Escriba wrote:
Le 27/04/13 09:39, Pierre T. a écrit :
On 04/26/2013 08:17 PM, Vicente J. Botet Escriba wrote:
Le 26/04/13 14:22, Pierre T. a écrit : I like this proposition but at first, it seems a bit "overkill". I would like to have more opinions about it. Through it seems to be less compatible with the "visitor" idea. The visitor resolves on types and most of the error code have a same type. So it would visit only one type. Right. But this independent on whether you use a wrapper exception or not, isn't it? Yes, it gives a good point to the traits.
* Default Constructor or constructor from nullexpect What is the advantage of having a expected instance that doesn't have neither a value nor an exception? How would the user manages with this possibility? Are you looking to make expect movable?
Basically, I noticed that classes without default constructor (or default state) are burdensome to use. Indeed, you cannot store an expected in a class as a member if not initialized in the constructor. Or doing something like:
expected<int> e; if(…) else(…) return e;
Through, I removed the default constructor because I found it unclear. I use a nullexcept because it was a good idea in Boost.Optional with nullopt. Yes it was one. But the definition of optional is there to allow a state that means value not present. expected<> is designed to have a value or an exception. Could you answer to the question How would the user manages with this possibility? By testing == nullexcept (operator== not in the proposal, sorry), however you are right, expected must contains an exception or a value. On the other hand, it's nice to provide a default constructor, so an idea could be to add a method "unitialized_error()" in the trait class. Why do you need a default constructor.
Finally, I'm not sure to understand how it's related to the movable ability of Boost.Expected. I let you try to define move move semantics for expected and you will see why this is related. After thinking more on this the moved object could present its exception_ptr if it has one, so move semantics doesn't force to have an uninitialized expected<>
* then/otherwise issues
But the design error is not on the otherwise function but on the then function.
Resuming, I'm not more for the 'then' function.
I'm totally agree with you. But I think that I misnamed the "otherwise" method. I think the "then" method is really useful, it's like an automaton. With e.then().then().then(), the treatment is stopped anytime when an error occurs in a then method. How would this be stopped? throwing and exception? It's not stopped but the "then" method launch the function only if expected contains a value. And what return if it not contains a value? Also, I think that the function taken by then should return void And which value would you pass to the second then call? The same. Sorry I don't follow. What The do you mean by the same? or an expected.
In fact the otherwise method is the error visitor. A common usage would be to chain it in the end:
e.then(...).then(...).then(...).visit_error(error_visitor);
visit_error is called if any "then" return an error. I found it wonderfully useful. This could be possible; It would need that then() returns an expression template storing all the functions on the chain and only
Maybe. But if we don't know how it is stopped chaining them has no sens. When the call to the function is asynchronous it is easy to stop it but synchronously it implies an exception which is against the goal of expected. the call to the visit_error would evaluate the chain. I don't think it is worth proving this lazy evaluation. To complete what I've said, the visit_error() would launch the visitor only if the expected contains an error. No lazy evaluation is needed. Ah I think I see now what was the initial intention. I suspect that you mean that as the result of e.then(f) would transport the exception stored on e if e is not valid, then the exception would be relayed until
Le 28/04/13 16:22, Pierre T. a écrit :
there is a call to visit_error and no call to any function will be done.
Yes this is quite similar if we had exceptions and we had a try/catch block
f0().then(f1).then(f2).then(f3).visit_error(error_visitor);
try {
f3(f2(f1(f0())));
} catch(...) {
error_visitor();
}
It would be great if we could have the equivalent for
try {
h(f(), g());
} catch(...) {
error_visitor();
}
when_all(f(), g()).then(h).visit_error(error_visitor);
when_all could return a expected
I'll try to send it before tomorrow. I will update it with the trait classes and the others comments you made. I just have a question about the proposal, should I use the Boost macro for noexcept,… or is it better (for a proposal) to write it with the standard tools ? I use to document using c++11 without any reference to the emulations.
Best, Vicente