[gsoc-2013] Boost.Expected

classic Classic list List threaded Threaded
64 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

[gsoc-2013] Boost.Expected

Pierre Talbot-2
Hello,

My name is Pierre Talbot, I participated to GSoC 2011 and began the
implementation of the Boost.Check library (for checking the validity of
any number having a check digit — credit card number, ISBN, …). It was
two years ago and the design is still evolving due to many variation
points in the code. One of the function looks like :

template  <typename  check_algo,
           typename  range>
boost::optional<typename  check_algo::checkdigit_type>
compute_checkdigit(const  range  &x);

Using boost::optional tell us that: "A check digit should be computed if
'x' is a valid sequence". Since 'x' has many reasons to be incorrect,
many errors could be raised. Based on a policy template class, it
launches exception or returns with an empty optional . Then I though a
lot about a better way to do it, allowing the user to get an exception
or an error code. But it was quite complex for a so little part of my
library… I decided that the policy "throw exception or nothing" should
be enough.

Yesterday, I watched the video of Mr. Alexandrescu on Boost.Expected and
I think it would be a very useful library. It could mainly be useful in
system programming (where many error codes can arise from a single
call), but in any code where many exception errors can be thrown (like
in Boost.Check).

As you suspected, I'm interested in coding Boost.Expected during the
summer as a GSoC student.

Firstly, it could be very useful to list the resources on the subject
(aside the talk), I have several articles that I will talk about later.

Secondly, and hoping you'll debate, I would like to ask your opinion
about several ideas and facts:

1) In the Boost project description, we can read: "adding a class
expected-or-error_code". Obviously, the main design decision made by
Alexandrescu is to consider that error code are exception. Do we need an
abstraction of exception/error code ? Why do you think a
"expected-or-error_code" class is interesting ?

2) Consider this code (from Alexandrescu slides) :

// Caller
string s = readline();
auto x = parseInt(s).get(); // throw on error
auto y = parseInt(s); // won’t throw
if (!y.valid()) {
// handle locally
if (y.hasException<std::invalid_argument>()) { // ------------------ <
The flagged line.
// no digits
...
}
y.get(); // just "re"throw
}

The flagged line has some tastes of "return to the past" flavor. Back to
the C procedural language, the basic error code handling system was a
lot criticized because:

* Readability of the code decrease ;
* Error handling occurs in the middle of the execution flow ;
* <Add your favourite reason here>.

Several links on the subjects (if you have others, I'm interested)

http://www.joelonsoftware.com/articles/Wrong.html
http://www.joelonsoftware.com/items/2003/10/13.html
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
http://nedbatchelder.com/text/exceptions-vs-status.html

Basically, only the last one is clearly for exception. The main argument
against the procedural approach is the readability. I would say that the
Expected approach just differ by allowing to rethrow exception. But if
you want to handle it, you must code multiple if-than-else statements.

So I considered a complementary approach working with Expected to handle
multiple error cases:

string visa_number = readline();
expected<char> expected_checkdigit = compute_checkdigit<visa>(visa_number);
if(expected_checkdigit.valid(visa_error_resolver))
{
visa_number += expected_checkdigit.get();
std::cout << visa_number << std::endl;
}

With this code, there is only a if statement, and no more multiple error
cases handles. But what is this error_resolver ?

It may be declared as :

// Somewhere in visa.hpp. A type list.
typedef error_list<size_error_exception, unknown_character_exception,
checkdigit_encoding_exception, …> visa_errors;

// Somewhere in the user code.
error_resolver<visa_errors, expected_type> visa_error_resolver; // in
this case, expected_type is a char.

// Initialize error handler on specific exception/errors.
visa_error_resolver.on<size_error_exception>(size_error_handler)
.on<unknown_character_exception>(unknown_character_exception)
...

Now we are agree that visa_error_resolver can be reused everywhere we
want to resolve an error on a visa number.

What are the handlers ? There are [Function|Functor|Lambda] (pick up
your favourite) with this form :

expected<ExpectedType> size_error_handler(const size_error_exception&)
expected<ExpectedType> unknown_character_exception(const
unknown_character_exception&)

Now you can understand for what the type list "error_list" stands for,
we can store these handlers into the error_resolver and call them
without any virtual cost.

Why the return type of error handler is expected<ExpectedType> ?

Consider this size_error_handler code :

expected<ReturnType> size_error_handler(const size_error_exception& e)
{
std::cout << "The number you gave has a bad size." << std::endl;
std::cout << "Enter it again : " << std::endl;
return read_visa_checkdigit();
}

read_visa_checkdigit can call recursively valid() until it's valid.
Though there are some ways to make this treatment iterative.

A basic treatment could be to print an warning message and just returns
(in this case, valid returns false):

expected<ReturnType> size_error_handler(const size_error_exception& e)
{
std::cout << "Warning: the VISA field is incorrect." << std::endl;
return expected<ReturnType>::fromException(e);
}

Results:
* The error code handling is delegated to specific functions ;
* The readability is still excellent ;
* You can easily re-use your error handler function ;
* If you don't like it, you can still throw exception on failure with
"get()".

I can code a "proof of concept" if you think this is a good idea.
Do not hesitate to comment it, point out programming pitfalls, request
further clarification, or anything you judge useful.

Thank you for reading it !
Pierre Talbot

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Klaim - Joël Lamotte
On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]> wrote:

> I can code a "proof of concept" if you think this is a good idea.


I'm willing to test it in real application if you make an implementation.
I think it is necessary to check the usability of this kind of library
directly in practice instead of pondering based on assumptions.
It's hard to figure out the side effects or using this tool. (at least to
me)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
In reply to this post by Pierre Talbot-2
Le 13/04/13 08:38, Pierre T. a écrit :

> Hello,
>
> My name is Pierre Talbot, I participated to GSoC 2011 and began the
> implementation of the Boost.Check library (for checking the validity
> of any number having a check digit — credit card number, ISBN, …). It
> was two years ago and the design is still evolving due to many
> variation points in the code. One of the function looks like :
>
> template  <typename  check_algo,
>           typename  range>
> boost::optional<typename  check_algo::checkdigit_type>
> compute_checkdigit(const  range  &x);
>
> Using boost::optional tell us that: "A check digit should be computed
> if 'x' is a valid sequence". Since 'x' has many reasons to be
> incorrect, many errors could be raised. Based on a policy template
> class, it launches exception or returns with an empty optional . Then
> I though a lot about a better way to do it, allowing the user to get
> an exception or an error code. But it was quite complex for a so
> little part of my library… I decided that the policy "throw exception
> or nothing" should be enough.
>
> Yesterday, I watched the video of Mr. Alexandrescu on Boost.Expected
> and I think it would be a very useful library. It could mainly be
> useful in system programming (where many error codes can arise from a
> single call), but in any code where many exception errors can be
> thrown (like in Boost.Check).
>
> As you suspected, I'm interested in coding Boost.Expected during the
> summer as a GSoC student.
>
Great.

> Firstly, it could be very useful to list the resources on the subject
> (aside the talk), I have several articles that I will talk about later.
>
> Secondly, and hoping you'll debate, I would like to ask your opinion
> about several ideas and facts:
>
> 1) In the Boost project description, we can read: "adding a class
> expected-or-error_code". Obviously, the main design decision made by
> Alexandrescu is to consider that error code are exception. Do we need
> an abstraction of exception/error code ? Why do you think a
> "expected-or-error_code" class is interesting ?
>
During discussion on how to implement c++ concurrent queue [1] it was
suggested in [2] that a value-or-status class will help to make the
interface more functional.

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3533.html
[2]
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CDQQFjAA&url=http%3A%2F%2Fgroups.google.com%2Fa%2Fisocpp.org%2Fgroup%2Fstd-proposals%2Fbrowse_thread%2Fthread%2F83db324ec26a0ab1%2Fb0cf6422f8d95803%3Fshow_docid%3Db0cf6422f8d95803&ei=Lz1pUYD1IJOR0QWtloDwDg&usg=AFQjCNFGiNLdGOaX9cse2vkRmTiXEUS5BA&sig2=Ho882VjpxYDrpnZow5wmxg&bvm=bv.45175338,d.d2k

instead of having

void pop(T&);
queue_op_status try_pop(T&);
T value_pop();

we could just have a

value-or-status pop();

This class is very close to Expected, but instead of storing an
exception, it stores the status (or error_code). It is a class that is
more adapted to lower interfaces that need to check the error code and
handle the error and for libraries that find expensive to throw an
exception or just can-not use exceptions. I would say that this class is
a must to have in the library.

> 2) Consider this code (from Alexandrescu slides) :
>
> // Caller
> string s = readline();
> auto x = parseInt(s).get(); // throw on error
> auto y = parseInt(s); // won’t throw
> if (!y.valid()) {
> // handle locally
> if (y.hasException<std::invalid_argument>()) { // ------------------ <
> The flagged line.
> // no digits
> ...
> }
> y.get(); // just "re"throw
> }
>
> The flagged line has some tastes of "return to the past" flavor. Back
> to the C procedural language, the basic error code handling system was
> a lot criticized because:
>
> * Readability of the code decrease ;
> * Error handling occurs in the middle of the execution flow ;
> * <Add your favourite reason here>.
>
Well as you know this is a question of taste and taste can not be discussed.
> Several links on the subjects (if you have others, I'm interested)
>
> http://www.joelonsoftware.com/articles/Wrong.html
> http://www.joelonsoftware.com/items/2003/10/13.html
> http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
> http://nedbatchelder.com/text/exceptions-vs-status.html
I don't find any more the slides of Alexandrescu's presentation. I have
them so if you can not find them neither I can send you them privately.
I 'll take a look to this links soon.
>
> Basically, only the last one is clearly for exception. The main
> argument against the procedural approach is the readability. I would
> say that the Expected approach just differ by allowing to rethrow
> exception. But if you want to handle it, you must code multiple
> if-than-else statements.
Agreed. expected can be see as a variant at two levels. The fist one
contains a value or an exception_ptr. So accept_visitor could have a
sens. In addition exception_ptr is some kind of any exception where the
exceptions can for a hierarchy. So any kind of hierarchical
accept_visitor could be applied as well.

Just note that the expected-or-error code can use a switch. No need for
if-then-else.

>
> So I considered a complementary approach working with Expected to
> handle multiple error cases:
>
> string visa_number = readline();
> expected<char> expected_checkdigit =
> compute_checkdigit<visa>(visa_number);
> if(expected_checkdigit.valid(visa_error_resolver))
> {
> visa_number += expected_checkdigit.get();
> std::cout << visa_number << std::endl;
> }
>
> With this code, there is only a if statement, and no more multiple
> error cases handles. But what is this error_resolver ?
>
> It may be declared as :
>
> // Somewhere in visa.hpp. A type list.
> typedef error_list<size_error_exception, unknown_character_exception,
> checkdigit_encoding_exception, …> visa_errors;
>
> // Somewhere in the user code.
> error_resolver<visa_errors, expected_type> visa_error_resolver; // in
> this case, expected_type is a char.
>
> // Initialize error handler on specific exception/errors.
> visa_error_resolver.on<size_error_exception>(size_error_handler)
> .on<unknown_character_exception>(unknown_character_exception)
> ...
>
This approach and other forms of the hierarchical visitor pattern can be
considered of course. I would not however use it with the valid function
but with a specific visit function.

if(expected_checkdigit.valid())
{
visa_number += expected_checkdigit.get();
std::cout << visa_number << std::endl;
} else {
   expected_checkdigit.visit(visa_error_resolver);
}

In addition this visitor could be applied to any exception_ptr, so we
can even provide it independently of the expected library as far as
expected provide access to the exception_ptr.

   visit(expected_checkdigit.get_exception_ptr(), visa_error_resolver);


> Now we are agree that visa_error_resolver can be reused everywhere we
> want to resolve an error on a visa number.
>
> What are the handlers ? There are [Function|Functor|Lambda] (pick up
> your favourite) with this form :
>
> expected<ExpectedType> size_error_handler(const size_error_exception&)
> expected<ExpectedType> unknown_character_exception(const
> unknown_character_exception&)
>
> Now you can understand for what the type list "error_list" stands for,
> we can store these handlers into the error_resolver and call them
> without any virtual cost.
I wold prefer to maintain expected<> as simple as possible and don't add
anything that is not mandatory.  But of course this is your talk.

>
> Why the return type of error handler is expected<ExpectedType> ?
>
> Consider this size_error_handler code :
>
> expected<ReturnType> size_error_handler(const size_error_exception& e)
> {
> std::cout << "The number you gave has a bad size." << std::endl;
> std::cout << "Enter it again : " << std::endl;
> return read_visa_checkdigit();
> }
>
> read_visa_checkdigit can call recursively valid() until it's valid.
> Though there are some ways to make this treatment iterative.
>
> A basic treatment could be to print an warning message and just
> returns (in this case, valid returns false):
>
> expected<ReturnType> size_error_handler(const size_error_exception& e)
> {
> std::cout << "Warning: the VISA field is incorrect." << std::endl;
> return expected<ReturnType>::fromException(e);
> }
>
> Results:
> * The error code handling is delegated to specific functions ;
> * The readability is still excellent ;
> * You can easily re-use your error handler function ;
> * If you don't like it, you can still throw exception on failure with
> "get()".
>
> I can code a "proof of concept" if you think this is a good idea.
I have started a basic implementation of expected<>. I would share it
with you soon. Maybe you can start to prototype the visitor pattern
applied to an exception_ptr.
> Do not hesitate to comment it, point out programming pitfalls, request
> further clarification, or anything you judge useful.
>
> Thank you for reading it !
>
I see you have a lot of excellent ideas. The fist thing to do is to make
a concrete proposal. Put all of what you have in mind. Make a realistic
proposal, a plan and ensure that you will be able to make ready for
review the library an the end of the GSoC period. I would not mentor a
proposal that has to propose for review to the Boost community at the
end of the summer.

Maybe other mentors could appreciate your proposal even if it don't
satisfy my constraints, so make the proposal you are confident with, at
the end it is youself that would work on it not the mentor.

Good luck,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
On 04/13/2013 01:23 PM, Vicente J. Botet Escriba wrote:

> Le 13/04/13 08:38, Pierre T. a écrit :
>> Hello,
>>
>> My name is Pierre Talbot, I participated to GSoC 2011 and began the
>> implementation of the Boost.Check library (for checking the validity
>> of any number having a check digit — credit card number, ISBN, …). It
>> was two years ago and the design is still evolving due to many
>> variation points in the code. One of the function looks like :
>>
>> template  <typename  check_algo,
>>           typename  range>
>> boost::optional<typename  check_algo::checkdigit_type>
>> compute_checkdigit(const  range  &x);
>>
>> Using boost::optional tell us that: "A check digit should be computed
>> if 'x' is a valid sequence". Since 'x' has many reasons to be
>> incorrect, many errors could be raised. Based on a policy template
>> class, it launches exception or returns with an empty optional . Then
>> I though a lot about a better way to do it, allowing the user to get
>> an exception or an error code. But it was quite complex for a so
>> little part of my library… I decided that the policy "throw exception
>> or nothing" should be enough.
>>
>> Yesterday, I watched the video of Mr. Alexandrescu on Boost.Expected
>> and I think it would be a very useful library. It could mainly be
>> useful in system programming (where many error codes can arise from a
>> single call), but in any code where many exception errors can be
>> thrown (like in Boost.Check).
>>
>> As you suspected, I'm interested in coding Boost.Expected during the
>> summer as a GSoC student.
>>
> Great.
>> Firstly, it could be very useful to list the resources on the subject
>> (aside the talk), I have several articles that I will talk about later.
>>
>> Secondly, and hoping you'll debate, I would like to ask your opinion
>> about several ideas and facts:
>>
>> 1) In the Boost project description, we can read: "adding a class
>> expected-or-error_code". Obviously, the main design decision made by
>> Alexandrescu is to consider that error code are exception. Do we need
>> an abstraction of exception/error code ? Why do you think a
>> "expected-or-error_code" class is interesting ?
>>
> During discussion on how to implement c++ concurrent queue [1] it was
> suggested in [2] that a value-or-status class will help to make the
> interface more functional.
>
> [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3533.html
> [2]
> http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CDQQFjAA&url=http%3A%2F%2Fgroups.google.com%2Fa%2Fisocpp.org%2Fgroup%2Fstd-proposals%2Fbrowse_thread%2Fthread%2F83db324ec26a0ab1%2Fb0cf6422f8d95803%3Fshow_docid%3Db0cf6422f8d95803&ei=Lz1pUYD1IJOR0QWtloDwDg&usg=AFQjCNFGiNLdGOaX9cse2vkRmTiXEUS5BA&sig2=Ho882VjpxYDrpnZow5wmxg&bvm=bv.45175338,d.d2k
>
> instead of having
>
> void pop(T&);
> queue_op_status try_pop(T&);
> T value_pop();
>
> we could just have a
>
> value-or-status pop();
>
> This class is very close to Expected, but instead of storing an
> exception, it stores the status (or error_code). It is a class that is
> more adapted to lower interfaces that need to check the error code and
> handle the error and for libraries that find expensive to throw an
> exception or just can-not use exceptions. I would say that this class
> is a must to have in the library.
>
>> 2) Consider this code (from Alexandrescu slides) :
>>
>> // Caller
>> string s = readline();
>> auto x = parseInt(s).get(); // throw on error
>> auto y = parseInt(s); // won’t throw
>> if (!y.valid()) {
>> // handle locally
>> if (y.hasException<std::invalid_argument>()) { // ------------------
>> < The flagged line.
>> // no digits
>> ...
>> }
>> y.get(); // just "re"throw
>> }
>>
>> The flagged line has some tastes of "return to the past" flavor. Back
>> to the C procedural language, the basic error code handling system
>> was a lot criticized because:
>>
>> * Readability of the code decrease ;
>> * Error handling occurs in the middle of the execution flow ;
>> * <Add your favourite reason here>.
>>
> Well as you know this is a question of taste and taste can not be
> discussed.
>> Several links on the subjects (if you have others, I'm interested)
>>
>> http://www.joelonsoftware.com/articles/Wrong.html
>> http://www.joelonsoftware.com/items/2003/10/13.html
>> http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
>> http://nedbatchelder.com/text/exceptions-vs-status.html
> I don't find any more the slides of Alexandrescu's presentation. I
> have them so if you can not find them neither I can send you them
> privately.
> I 'll take a look to this links soon.
In the video comments, there is this link :
https://skydrive.live.com/?cid=f1b8ff18a2aec5c5&id=F1B8FF18A2AEC5C5!1158&authkey=!APo6bfP5sJ8EmH4

>>
>> Basically, only the last one is clearly for exception. The main
>> argument against the procedural approach is the readability. I would
>> say that the Expected approach just differ by allowing to rethrow
>> exception. But if you want to handle it, you must code multiple
>> if-than-else statements.
> Agreed. expected can be see as a variant at two levels. The fist one
> contains a value or an exception_ptr. So accept_visitor could have a
> sens. In addition exception_ptr is some kind of any exception where
> the exceptions can for a hierarchy. So any kind of hierarchical
> accept_visitor could be applied as well.
>
> Just note that the expected-or-error code can use a switch. No need
> for if-then-else.
switch and if-then-else are quite similar, aren't they?

>>
>> So I considered a complementary approach working with Expected to
>> handle multiple error cases:
>>
>> string visa_number = readline();
>> expected<char> expected_checkdigit =
>> compute_checkdigit<visa>(visa_number);
>> if(expected_checkdigit.valid(visa_error_resolver))
>> {
>> visa_number += expected_checkdigit.get();
>> std::cout << visa_number << std::endl;
>> }
>>
>> With this code, there is only a if statement, and no more multiple
>> error cases handles. But what is this error_resolver ?
>>
>> It may be declared as :
>>
>> // Somewhere in visa.hpp. A type list.
>> typedef error_list<size_error_exception, unknown_character_exception,
>> checkdigit_encoding_exception, …> visa_errors;
>>
>> // Somewhere in the user code.
>> error_resolver<visa_errors, expected_type> visa_error_resolver; // in
>> this case, expected_type is a char.
>>
>> // Initialize error handler on specific exception/errors.
>> visa_error_resolver.on<size_error_exception>(size_error_handler)
>> .on<unknown_character_exception>(unknown_character_exception)
>> ...
>>
> This approach and other forms of the hierarchical visitor pattern can
> be considered of course. I would not however use it with the valid
> function but with a specific visit function.
>
> if(expected_checkdigit.valid())
> {
> visa_number += expected_checkdigit.get();
> std::cout << visa_number << std::endl;
> } else {
>   expected_checkdigit.visit(visa_error_resolver);
> }
>
> In addition this visitor could be applied to any exception_ptr, so we
> can even provide it independently of the expected library as far as
> expected provide access to the exception_ptr.
>
>   visit(expected_checkdigit.get_exception_ptr(), visa_error_resolver);
This is two more lines for a very common case. We should rename
valid(error_resolver&) for validate ? Or feel free to propose any
suggestions.

>
>> Now we are agree that visa_error_resolver can be reused everywhere we
>> want to resolve an error on a visa number.
>>
>> What are the handlers ? There are [Function|Functor|Lambda] (pick up
>> your favourite) with this form :
>>
>> expected<ExpectedType> size_error_handler(const size_error_exception&)
>> expected<ExpectedType> unknown_character_exception(const
>> unknown_character_exception&)
>>
>> Now you can understand for what the type list "error_list" stands
>> for, we can store these handlers into the error_resolver and call
>> them without any virtual cost.
> I wold prefer to maintain expected<> as simple as possible and don't
> add anything that is not mandatory.  But of course this is your talk.
I'm not sure that my explanation is clear. In fact these two functions
are not related to expected<>. They are the visitor.

>>
>> Why the return type of error handler is expected<ExpectedType> ?
>>
>> Consider this size_error_handler code :
>>
>> expected<ReturnType> size_error_handler(const size_error_exception& e)
>> {
>> std::cout << "The number you gave has a bad size." << std::endl;
>> std::cout << "Enter it again : " << std::endl;
>> return read_visa_checkdigit();
>> }
>>
>> read_visa_checkdigit can call recursively valid() until it's valid.
>> Though there are some ways to make this treatment iterative.
>>
>> A basic treatment could be to print an warning message and just
>> returns (in this case, valid returns false):
>>
>> expected<ReturnType> size_error_handler(const size_error_exception& e)
>> {
>> std::cout << "Warning: the VISA field is incorrect." << std::endl;
>> return expected<ReturnType>::fromException(e);
>> }
>>
>> Results:
>> * The error code handling is delegated to specific functions ;
>> * The readability is still excellent ;
>> * You can easily re-use your error handler function ;
>> * If you don't like it, you can still throw exception on failure with
>> "get()".
>>
>> I can code a "proof of concept" if you think this is a good idea.
> I have started a basic implementation of expected<>. I would share it
> with you soon. Maybe you can start to prototype the visitor pattern
> applied to an exception_ptr.
I have the Alexandrescu class, copied from the slides. But I would be
glad to see yours too.

>> Do not hesitate to comment it, point out programming pitfalls,
>> request further clarification, or anything you judge useful.
>>
>> Thank you for reading it !
>>
> I see you have a lot of excellent ideas. The fist thing to do is to
> make a concrete proposal. Put all of what you have in mind. Make a
> realistic proposal, a plan and ensure that you will be able to make
> ready for review the library an the end of the GSoC period. I would
> not mentor a proposal that has to propose for review to the Boost
> community at the end of the summer.
>
> Maybe other mentors could appreciate your proposal even if it don't
> satisfy my constraints, so make the proposal you are confident with,
> at the end it is youself that would work on it not the mentor.
>
> Good luck,
> Vicente

Before going further with an implementation try, I would like to have
your opinion on this simple idea:

I'm not sure that expected should encapsulate an exception. Moreover the
std::exception_pointer introduces virtuality that could be quite
intrusive for the low-level interface.
I propose that expected use a type list of error such as :

typedef ErrorList<BadLengthError, OverflowError, …> MyErrorList;
typedef expected<T, MyErrorList> ExpectedReturnType;

ExpectedReturnType value = …;

* The visitor could have the advantage to be static.
* The user can put error class, exception error class. We could
specialize it for error code too I guess.

I have further facilities ideas that I will show you later if you think
that could be a good compromise.

Thanks for the comments,
Pierre Talbot

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
Le 13/04/13 16:24, Pierre T. a écrit :

> On 04/13/2013 01:23 PM, Vicente J. Botet Escriba wrote:
>> Le 13/04/13 08:38, Pierre T. a écrit :
>>> Hello,
>>>
>>> My name is Pierre Talbot, I participated to GSoC 2011 and began the
>>> implementation of the Boost.Check library (for checking the validity
>>> of any number having a check digit — credit card number, ISBN, …).
>>> It was two years ago and the design is still evolving due to many
>>> variation points in the code. One of the function looks like :
>>>
>>> template  <typename  check_algo,
>>>           typename  range>
>>> boost::optional<typename  check_algo::checkdigit_type>
>>> compute_checkdigit(const  range  &x);
>>>
>>> Using boost::optional tell us that: "A check digit should be
>>> computed if 'x' is a valid sequence". Since 'x' has many reasons to
>>> be incorrect, many errors could be raised. Based on a policy
>>> template class, it launches exception or returns with an empty
>>> optional . Then I though a lot about a better way to do it, allowing
>>> the user to get an exception or an error code. But it was quite
>>> complex for a so little part of my library… I decided that the
>>> policy "throw exception or nothing" should be enough.
>>>
>>> Yesterday, I watched the video of Mr. Alexandrescu on Boost.Expected
>>> and I think it would be a very useful library. It could mainly be
>>> useful in system programming (where many error codes can arise from
>>> a single call), but in any code where many exception errors can be
>>> thrown (like in Boost.Check).
>>>
>>> As you suspected, I'm interested in coding Boost.Expected during the
>>> summer as a GSoC student.
>>>
>> Great.
>>> Firstly, it could be very useful to list the resources on the
>>> subject (aside the talk), I have several articles that I will talk
>>> about later.
>>>
>>> Secondly, and hoping you'll debate, I would like to ask your opinion
>>> about several ideas and facts:
>>>
>>> 1) In the Boost project description, we can read: "adding a class
>>> expected-or-error_code". Obviously, the main design decision made by
>>> Alexandrescu is to consider that error code are exception. Do we
>>> need an abstraction of exception/error code ? Why do you think a
>>> "expected-or-error_code" class is interesting ?
>>>
>> During discussion on how to implement c++ concurrent queue [1] it was
>> suggested in [2] that a value-or-status class will help to make the
>> interface more functional.
>>
>> [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3533.html
>> [2]
>> http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CDQQFjAA&url=http%3A%2F%2Fgroups.google.com%2Fa%2Fisocpp.org%2Fgroup%2Fstd-proposals%2Fbrowse_thread%2Fthread%2F83db324ec26a0ab1%2Fb0cf6422f8d95803%3Fshow_docid%3Db0cf6422f8d95803&ei=Lz1pUYD1IJOR0QWtloDwDg&usg=AFQjCNFGiNLdGOaX9cse2vkRmTiXEUS5BA&sig2=Ho882VjpxYDrpnZow5wmxg&bvm=bv.45175338,d.d2k
>>
>> instead of having
>>
>> void pop(T&);
>> queue_op_status try_pop(T&);
>> T value_pop();
>>
>> we could just have a
>>
>> value-or-status pop();
>>
>> This class is very close to Expected, but instead of storing an
>> exception, it stores the status (or error_code). It is a class that
>> is more adapted to lower interfaces that need to check the error code
>> and handle the error and for libraries that find expensive to throw
>> an exception or just can-not use exceptions. I would say that this
>> class is a must to have in the library.
>>
>>> 2) Consider this code (from Alexandrescu slides) :
>>>
>>> // Caller
>>> string s = readline();
>>> auto x = parseInt(s).get(); // throw on error
>>> auto y = parseInt(s); // won’t throw
>>> if (!y.valid()) {
>>> // handle locally
>>> if (y.hasException<std::invalid_argument>()) { // ------------------
>>> < The flagged line.
>>> // no digits
>>> ...
>>> }
>>> y.get(); // just "re"throw
>>> }
>>>
>>> The flagged line has some tastes of "return to the past" flavor.
>>> Back to the C procedural language, the basic error code handling
>>> system was a lot criticized because:
>>>
>>> * Readability of the code decrease ;
>>> * Error handling occurs in the middle of the execution flow ;
>>> * <Add your favourite reason here>.
>>>
>> Well as you know this is a question of taste and taste can not be
>> discussed.
>>> Several links on the subjects (if you have others, I'm interested)
>>>
>>> http://www.joelonsoftware.com/articles/Wrong.html
>>> http://www.joelonsoftware.com/items/2003/10/13.html
>>> http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
>>> http://nedbatchelder.com/text/exceptions-vs-status.html
>> I don't find any more the slides of Alexandrescu's presentation. I
>> have them so if you can not find them neither I can send you them
>> privately.
>> I 'll take a look to this links soon.
> In the video comments, there is this link :
> https://skydrive.live.com/?cid=f1b8ff18a2aec5c5&id=F1B8FF18A2AEC5C5!1158&authkey=!APo6bfP5sJ8EmH4
>>>
>>> Basically, only the last one is clearly for exception. The main
>>> argument against the procedural approach is the readability. I would
>>> say that the Expected approach just differ by allowing to rethrow
>>> exception. But if you want to handle it, you must code multiple
>>> if-than-else statements.
>> Agreed. expected can be see as a variant at two levels. The fist one
>> contains a value or an exception_ptr. So accept_visitor could have a
>> sens. In addition exception_ptr is some kind of any exception where
>> the exceptions can for a hierarchy. So any kind of hierarchical
>> accept_visitor could be applied as well.
>>
>> Just note that the expected-or-error code can use a switch. No need
>> for if-then-else.
> switch and if-then-else are quite similar, aren't they?
>>>
>>> So I considered a complementary approach working with Expected to
>>> handle multiple error cases:
>>>
>>> string visa_number = readline();
>>> expected<char> expected_checkdigit =
>>> compute_checkdigit<visa>(visa_number);
>>> if(expected_checkdigit.valid(visa_error_resolver))
>>> {
>>> visa_number += expected_checkdigit.get();
>>> std::cout << visa_number << std::endl;
>>> }
>>>
>>> With this code, there is only a if statement, and no more multiple
>>> error cases handles. But what is this error_resolver ?
>>>
>>> It may be declared as :
>>>
>>> // Somewhere in visa.hpp. A type list.
>>> typedef error_list<size_error_exception,
>>> unknown_character_exception, checkdigit_encoding_exception, …>
>>> visa_errors;
>>>
>>> // Somewhere in the user code.
>>> error_resolver<visa_errors, expected_type> visa_error_resolver; //
>>> in this case, expected_type is a char.
>>>
>>> // Initialize error handler on specific exception/errors.
>>> visa_error_resolver.on<size_error_exception>(size_error_handler)
>>> .on<unknown_character_exception>(unknown_character_exception)
>>> ...
>>>
>> This approach and other forms of the hierarchical visitor pattern can
>> be considered of course. I would not however use it with the valid
>> function but with a specific visit function.
>>
>> if(expected_checkdigit.valid())
>> {
>> visa_number += expected_checkdigit.get();
>> std::cout << visa_number << std::endl;
>> } else {
>>   expected_checkdigit.visit(visa_error_resolver);
>> }
>>
>> In addition this visitor could be applied to any exception_ptr, so we
>> can even provide it independently of the expected library as far as
>> expected provide access to the exception_ptr.
>>
>>   visit(expected_checkdigit.get_exception_ptr(), visa_error_resolver);
> This is two more lines for a very common case. We should rename
> valid(error_resolver&) for validate ? Or feel free to propose any
> suggestions.
>>
>>> Now we are agree that visa_error_resolver can be reused everywhere
>>> we want to resolve an error on a visa number.
>>>
>>> What are the handlers ? There are [Function|Functor|Lambda] (pick up
>>> your favourite) with this form :
>>>
>>> expected<ExpectedType> size_error_handler(const size_error_exception&)
>>> expected<ExpectedType> unknown_character_exception(const
>>> unknown_character_exception&)
>>>
>>> Now you can understand for what the type list "error_list" stands
>>> for, we can store these handlers into the error_resolver and call
>>> them without any virtual cost.
>> I wold prefer to maintain expected<> as simple as possible and don't
>> add anything that is not mandatory.  But of course this is your talk.
> I'm not sure that my explanation is clear. In fact these two functions
> are not related to expected<>. They are the visitor.
>>>
>>> Why the return type of error handler is expected<ExpectedType> ?
>>>
>>> Consider this size_error_handler code :
>>>
>>> expected<ReturnType> size_error_handler(const size_error_exception& e)
>>> {
>>> std::cout << "The number you gave has a bad size." << std::endl;
>>> std::cout << "Enter it again : " << std::endl;
>>> return read_visa_checkdigit();
>>> }
>>>
>>> read_visa_checkdigit can call recursively valid() until it's valid.
>>> Though there are some ways to make this treatment iterative.
>>>
>>> A basic treatment could be to print an warning message and just
>>> returns (in this case, valid returns false):
>>>
>>> expected<ReturnType> size_error_handler(const size_error_exception& e)
>>> {
>>> std::cout << "Warning: the VISA field is incorrect." << std::endl;
>>> return expected<ReturnType>::fromException(e);
>>> }
>>>
>>> Results:
>>> * The error code handling is delegated to specific functions ;
>>> * The readability is still excellent ;
>>> * You can easily re-use your error handler function ;
>>> * If you don't like it, you can still throw exception on failure
>>> with "get()".
>>>
>>> I can code a "proof of concept" if you think this is a good idea.
>> I have started a basic implementation of expected<>. I would share it
>> with you soon. Maybe you can start to prototype the visitor pattern
>> applied to an exception_ptr.
> I have the Alexandrescu class, copied from the slides. But I would be
> glad to see yours too.
>>> Do not hesitate to comment it, point out programming pitfalls,
>>> request further clarification, or anything you judge useful.
>>>
>>> Thank you for reading it !
>>>
>> I see you have a lot of excellent ideas. The fist thing to do is to
>> make a concrete proposal. Put all of what you have in mind. Make a
>> realistic proposal, a plan and ensure that you will be able to make
>> ready for review the library an the end of the GSoC period. I would
>> not mentor a proposal that has to propose for review to the Boost
>> community at the end of the summer.
>>
>> Maybe other mentors could appreciate your proposal even if it don't
>> satisfy my constraints, so make the proposal you are confident with,
>> at the end it is youself that would work on it not the mentor.
>>
>> Good luck,
>> Vicente
>
> Before going further with an implementation try, I would like to have
> your opinion on this simple idea:
>
> I'm not sure that expected should encapsulate an exception. Moreover
> the std::exception_pointer introduces virtuality that could be quite
> intrusive for the low-level interface.
No more than throwing exceptions. This is why we need
expected-or-error-code.
> I propose that expected use a type list of error such as :
>
> typedef ErrorList<BadLengthError, OverflowError, …> MyErrorList;
> typedef expected<T, MyErrorList> ExpectedReturnType;
>
> ExpectedReturnType value = …;
>
> * The visitor could have the advantage to be static.
I have not taken the time to analyze this static approach.
What is the advantage of making the exceptions static?
Humm, this is quite close to declare the exceptions a function can throw
which we know is no so good.
What would be the size of this expected type?
> * The user can put error class, exception error class. We could
> specialize it for error code too I guess.
Humm, this start to be to close to boost::variant. What would be the
real difference with Boost.Variant?
>
> I have further facilities ideas that I will show you later if you
> think that could be a good compromise.
>
My intention was to have a expected<> class that is quite close to the
one of Alexandrescu to which we can add things that improve them but no
things that make it worst. Using more space than Expected make it worst
for me.
Remember that in addition Expected should be movable if  T is movable.

Next implement expected-or-error_code.

This doesn't means that you can not explore alternative design if you
have enough time, compare them, and provide some performances figures
that would help the user to make its choice. Yes this will be really great.

Let me know if this in line respect your expectations.

Best,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
In reply to this post by Klaim - Joël Lamotte
On 04/13/2013 12:57 PM, Klaim - Joël Lamotte wrote:
> On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]> wrote:
>
>> I can code a "proof of concept" if you think this is a good idea.
>
> I'm willing to test it in real application if you make an implementation.
> I think it is necessary to check the usability of this kind of library
> directly in practice instead of pondering based on assumptions.
> It's hard to figure out the side effects or using this tool. (at least to
> me)
Hello,

I gave a try at the implementation of the expected_or_error class.
I used the boost layout to package the implementation, you can download
it here : http://www.hyc.io/boost/expected.zip
Finally, feel free to explore the documentation I wrote
http://www.hyc.io/boost/index.html

Note: In the example folder, the "b2" command never terminates (but
correctly generates binaries), I can't figure out why.

Please, do not hesitate to give me advices and critics to improve this
library and my future proposal.

Thank you,
Pierre Talbot.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Steven Watanabe-4
AMDG

On 04/19/2013 07:36 AM, Pierre T. wrote:

>
> I gave a try at the implementation of the expected_or_error class.
> I used the boost layout to package the implementation, you can download
> it here : http://www.hyc.io/boost/expected.zip
> Finally, feel free to explore the documentation I wrote
> http://www.hyc.io/boost/index.html
>
> Note: In the example folder, the "b2" command never terminates (but
> correctly generates binaries), I can't figure out why.
>

Is any subprocess still running?  b2 doesn't print
any output for a command until it finishes (to avoid
interleaving for parallel builds), so the last output
is an action that has completed successfully, /not/
the action that is currently running.  What platform
is this on?

> Please, do not hesitate to give me advices and critics to improve this
> library and my future proposal.
>

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
On 04/19/2013 05:01 PM, Steven Watanabe wrote:

> AMDG
>
> On 04/19/2013 07:36 AM, Pierre T. wrote:
>> I gave a try at the implementation of the expected_or_error class.
>> I used the boost layout to package the implementation, you can download
>> it here : http://www.hyc.io/boost/expected.zip
>> Finally, feel free to explore the documentation I wrote
>> http://www.hyc.io/boost/index.html
>>
>> Note: In the example folder, the "b2" command never terminates (but
>> correctly generates binaries), I can't figure out why.
>>
> Is any subprocess still running?  b2 doesn't print
> any output for a command until it finishes (to avoid
> interleaving for parallel builds), so the last output
> is an action that has completed successfully, /not/
> the action that is currently running.  What platform
> is this on?
I'm not sure what you mean with "subprocess", only the b2 command is
returned by "ps -a | grep b2".
Here the output of b2 :

...found 31 targets...
...updating 15 targets...
common.mkdir bin
common.mkdir bin/expected_or_error_example.test
common.mkdir bin/expected_or_error_example.test/gcc-4.7
common.mkdir bin/expected_or_error_example.test/gcc-4.7/debug
gcc.compile.c++
bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example.o
gcc.link
bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example
^C

I'm on Linux (Ubuntu). But on this same platform, I already successful
run bjam with another project.

Thanks for help,
Pierre Talbot.
>> Please, do not hesitate to give me advices and critics to improve this
>> library and my future proposal.
>>
> In Christ,
> Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
Le 19/04/13 17:21, Pierre T. a écrit :

> On 04/19/2013 05:01 PM, Steven Watanabe wrote:
>> AMDG
>>
>> On 04/19/2013 07:36 AM, Pierre T. wrote:
>>> I gave a try at the implementation of the expected_or_error class.
>>> I used the boost layout to package the implementation, you can download
>>> it here : http://www.hyc.io/boost/expected.zip
>>> Finally, feel free to explore the documentation I wrote
>>> http://www.hyc.io/boost/index.html
>>>
>>> Note: In the example folder, the "b2" command never terminates (but
>>> correctly generates binaries), I can't figure out why.
>>>
>> Is any subprocess still running?  b2 doesn't print
>> any output for a command until it finishes (to avoid
>> interleaving for parallel builds), so the last output
>> is an action that has completed successfully, /not/
>> the action that is currently running.  What platform
>> is this on?
> I'm not sure what you mean with "subprocess", only the b2 command is
> returned by "ps -a | grep b2".
> Here the output of b2 :
>
> ...found 31 targets...
> ...updating 15 targets...
> common.mkdir bin
> common.mkdir bin/expected_or_error_example.test
> common.mkdir bin/expected_or_error_example.test/gcc-4.7
> common.mkdir bin/expected_or_error_example.test/gcc-4.7/debug
> gcc.compile.c++
> bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example.o
> gcc.link
> bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example
> ^C
>
> I'm on Linux (Ubuntu). But on this same platform, I already successful
> run bjam with another project.
>
>

I suspect that your program is expecting you give the password, but when
you use b2 you can not even see the request for it. Steve is there a way
to give a file as input to the test?

How we should bjam setup this kind of examples so that we can interact
with stdin/stdout?

Best,
Vicente

Best,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Steven Watanabe-4
AMDG

On 04/19/2013 10:03 AM, Vicente J. Botet Escriba wrote:

> Le 19/04/13 17:21, Pierre T. a écrit :
>>
>> gcc.link
>> bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example
>>
>> ^C
>>
>> I'm on Linux (Ubuntu). But on this same platform, I already successful
>> run bjam with another project.
>>
>>
>
> I suspect that your program is expecting you give the password, but when
> you use b2 you can not even see the request for it. Steve is there a way
> to give a file as input to the test?
>
> How we should bjam setup this kind of examples so that we can interact
> with stdin/stdout?
>

Programs run under a build tool should
not require any action from the user.
You could try redirecting stdin like this:

path-constant input-file : input.txt ;
run mytest.cpp : < \"$(input-file)\" ;

I haven't tested whether this actually works, though.

In Christ,
Steven Watanabe


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
Le 19/04/13 19:37, Steven Watanabe a écrit :

> AMDG
>
> On 04/19/2013 10:03 AM, Vicente J. Botet Escriba wrote:
>> Le 19/04/13 17:21, Pierre T. a écrit :
>>> gcc.link
>>> bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example
>>>
>>> ^C
>>>
>>> I'm on Linux (Ubuntu). But on this same platform, I already successful
>>> run bjam with another project.
>>>
>>>
>> I suspect that your program is expecting you give the password, but when
>> you use b2 you can not even see the request for it. Steve is there a way
>> to give a file as input to the test?
>>
>> How we should bjam setup this kind of examples so that we can interact
>> with stdin/stdout?
>>
> Programs run under a build tool should
> not require any action from the user.
Agreed. Should we use instead for these kind of examples just the exe
rule and execute the example off-line?
> You could try redirecting stdin like this:
>
> path-constant input-file : input.txt ;
> run mytest.cpp : < \"$(input-file)\" ;
>
> I haven't tested whether this actually works, though.
>
>
Thanks, I will try it.
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
On 04/20/2013 12:33 AM, Vicente J. Botet Escriba wrote:

> Le 19/04/13 19:37, Steven Watanabe a écrit :
>> AMDG
>>
>> On 04/19/2013 10:03 AM, Vicente J. Botet Escriba wrote:
>>> Le 19/04/13 17:21, Pierre T. a écrit :
>>>> gcc.link
>>>> bin/expected_or_error_example.test/gcc-4.7/debug/expected_or_error_example
>>>>
>>>>
>>>> ^C
>>>>
>>>> I'm on Linux (Ubuntu). But on this same platform, I already successful
>>>> run bjam with another project.
>>>>
>>>>
>>> I suspect that your program is expecting you give the password, but
>>> when
>>> you use b2 you can not even see the request for it. Steve is there a
>>> way
>>> to give a file as input to the test?
>>>
>>> How we should bjam setup this kind of examples so that we can interact
>>> with stdin/stdout?
>>>
>> Programs run under a build tool should
>> not require any action from the user.
> Agreed. Should we use instead for these kind of examples just the exe
> rule and execute the example off-line?
Good to know.

>> You could try redirecting stdin like this:
>>
>> path-constant input-file : input.txt ;
>> run mytest.cpp : < \"$(input-file)\" ;
>>
>> I haven't tested whether this actually works, though.
>>
>>
> Thanks, I will try it.
> Vicente

I removed the std::cin instruction and replace it with a string array,
it works now :-)
If you have any other comments, please let me know.

Thanks.
Pierre T.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
In reply to this post by Pierre Talbot-2
Le 19/04/13 16:36, Pierre T. a écrit :

> On 04/13/2013 12:57 PM, Klaim - Joël Lamotte wrote:
>> On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]> wrote:
>>
>>> I can code a "proof of concept" if you think this is a good idea.
>>
>> I'm willing to test it in real application if you make an
>> implementation.
>> I think it is necessary to check the usability of this kind of library
>> directly in practice instead of pondering based on assumptions.
>> It's hard to figure out the side effects or using this tool. (at
>> least to
>> me)
> Hello,
>
> I gave a try at the implementation of the expected_or_error class.
> I used the boost layout to package the implementation, you can
> download it here : http://www.hyc.io/boost/expected.zip
> Finally, feel free to explore the documentation I wrote
> http://www.hyc.io/boost/index.html
>
> Please, do not hesitate to give me advices and critics to improve this
> library and my future proposal.
>
>
Hi,

glad to see you are exploring the different alternatives. This is really
a good starting point.

See attached my draft (not tested) of expected which is based on
Alexandrescu class but adapted to boost notation and making it portable
to c++98 compilers. In addition I added some additional helper functions.


Now it is time to make a concrete proposal for you candidature.

Best,
Vicente



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

expected.hpp (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
Le 20/04/13 10:50, Vicente J. Botet Escriba a écrit :

> Le 19/04/13 16:36, Pierre T. a écrit :
>> On 04/13/2013 12:57 PM, Klaim - Joël Lamotte wrote:
>>> On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]> wrote:
>>>
>>>
>> Hello,
>>
>> I gave a try at the implementation of the expected_or_error class.
>> I used the boost layout to package the implementation, you can
>> download it here : http://www.hyc.io/boost/expected.zip
>> Finally, feel free to explore the documentation I wrote
>> http://www.hyc.io/boost/index.html
>>
>> Please, do not hesitate to give me advices and critics to improve
>> this library and my future proposal.
>>
>>
> Hi,
>
> glad to see you are exploring the different alternatives. This is
> really a good starting point.
>
> Now it is time to make a concrete proposal for you candidature.
>
>

Hi again,

I have some questions:

Do you think that expected and/or expected_or_error could/should have
value semantics, that is define operator==?
I don't know if the const get function should be provided?
   const T& get() const { return value; }
what do you think?

What about an explicit conversion to the underlying type that behaves as
the get function?
What about an explicit conversion to bool that behaves as the valid
function?
Do you pretend to provide a C++98 portable implementation?
How the expected_or_error behaves in the presence of copy constructor
exceptions?
Which expected_or_error<> functions can be declared as noexcept?
Which expected<> functions can be declared as noexcept?

Best,
Vicente





_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
On 04/20/2013 11:36 AM, Vicente J. Botet Escriba wrote:

> Le 20/04/13 10:50, Vicente J. Botet Escriba a écrit :
>> Le 19/04/13 16:36, Pierre T. a écrit :
>>> On 04/13/2013 12:57 PM, Klaim - Joël Lamotte wrote:
>>>> On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]> wrote:
>>>>
>>>>
>>> Hello,
>>>
>>> I gave a try at the implementation of the expected_or_error class.
>>> I used the boost layout to package the implementation, you can
>>> download it here : http://www.hyc.io/boost/expected.zip
>>> Finally, feel free to explore the documentation I wrote
>>> http://www.hyc.io/boost/index.html
>>>
>>> Please, do not hesitate to give me advices and critics to improve
>>> this library and my future proposal.
>>>
>>>
>> Hi,
>>
>> glad to see you are exploring the different alternatives. This is
>> really a good starting point.
>>
>> Now it is time to make a concrete proposal for you candidature.
>>
>>
>
> Hi again,
>
Hi,
> I have some questions:
>
> Do you think that expected and/or expected_or_error could/should have
> value semantics, that is define operator==?
I don't have any use cases where expected/expected_or_error would have
value semantics.
Even if the underlying value has value semantics, you can't compare
exceptions and you rarely compare two error code encapsulated into two
variables (of course you often compare a variable and a constant error
code).
So, unless we give me good arguments, I would consider it as entity
semantics.

> I don't know if the const get function should be provided?
>   const T& get() const { return value; }
> what do you think?
Because expected<> aims to always be a return value, I would be say we
don't need it.
Nevertheless, the user could pass expected to a function by const-ref.
So to enable any programming style, I would let it there.

>
> What about an explicit conversion to the underlying type that behaves
> as the get function?
Is there really an interest to do (type)e instead of e.get() ? I'm not
sure. However I don't have any arguments against it.

> What about an explicit conversion to bool that behaves as the valid
> function?
Yes, even an implicit conversion to bool could be useful.

> Do you pretend to provide a C++98 portable implementation?
I'm pretty sure it's possible with some features disable such as the
move semantics.
Should we use boost::variant to facilitate the C++98 variant
implementation ?

> How the expected_or_error behaves in the presence of copy constructor
> exceptions?
It doesn't capture the exception and the responsibility of handling this
exception is delegated to higher layer.

> Which expected_or_error<> functions can be declared as noexcept?

Constructor/operator=: noexcept if the T/ErrorType copy/move constructor
doesn't throw.
Destructor: noexcept if the T/ErrorType destructor doesn't throw.
Swap: noexcept if the move constructor(c++11)/ copy constructor(c++98)
doesn't throw.

Observer and getter can be declared as no except.

> Which expected<> functions can be declared as noexcept?
>
Same as above plus:

noexcept:
fromException(std::exception_ptr p);
fromException();
fromCode(F fun);

> Best,
> Vicente
>
Your questions are interesting and I'm not sure I gave the best answers.
Some of the design decisions are hard to guess without any feedback from
users (such as the value semantics).

I like your implementation of expected, the "then" method is similar to
what I tried to achieve with "resolve".
Maybe we could have a method "otherwise" which do the same than "then"
but with the error ?

I'll send soon my proposal to the boost mailing-list for any
reviews/comments.

Thank you,
Pierre Talbot.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
Le 20/04/13 14:44, Pierre T. a écrit :

> On 04/20/2013 11:36 AM, Vicente J. Botet Escriba wrote:
>> Le 20/04/13 10:50, Vicente J. Botet Escriba a écrit :
>>> Le 19/04/13 16:36, Pierre T. a écrit :
>>>> On 04/13/2013 12:57 PM, Klaim - Joël Lamotte wrote:
>>>>> On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]>
>>>>> wrote:
>>>>>
>>>>>
>>>> Hello,
>>>>
>>>> I gave a try at the implementation of the expected_or_error class.
>>>> I used the boost layout to package the implementation, you can
>>>> download it here : http://www.hyc.io/boost/expected.zip
>>>> Finally, feel free to explore the documentation I wrote
>>>> http://www.hyc.io/boost/index.html
>>>>
>>>> Please, do not hesitate to give me advices and critics to improve
>>>> this library and my future proposal.
>>>>
>>>>
>>> Hi,
>>>
>>> glad to see you are exploring the different alternatives. This is
>>> really a good starting point.
>>>
>>> Now it is time to make a concrete proposal for you candidature.
>>>
>>>
>>
>> Hi again,
>>
> Hi,
>> I have some questions:
>>
>> Do you think that expected and/or expected_or_error could/should have
>> value semantics, that is define operator==?
> I don't have any use cases where expected/expected_or_error would have
> value semantics.
> Even if the underlying value has value semantics, you can't compare
> exceptions and you rarely compare two error code encapsulated into two
> variables (of course you often compare a variable and a constant error
> code).
> So, unless we give me good arguments, I would consider it as entity
> semantics.
I was wondering as optional<T> has value semantics and no value is
different from any optional valued. I don't know yet if it has a sens to
define it for expected_or_error and you are right we need a valid use case.
>
>> I don't know if the const get function should be provided?
>>   const T& get() const { return value; }
>> what do you think?
> Because expected<> aims to always be a return value, I would be say we
> don't need it.
> Nevertheless, the user could pass expected to a function by const-ref.
> So to enable any programming style, I would let it there.
Sorry, I meant the non-const. Anyway, I guess that it is there to make
easier to pass a non-const to a function expecting a T&.

expected<T> r =f();
g(r.get());

>
>>
>> What about an explicit conversion to the underlying type that behaves
>> as the get function?
> Is there really an interest to do (type)e instead of e.get() ? I'm not
> sure. However I don't have any arguments against it.
>
>> What about an explicit conversion to bool that behaves as the valid
>> function?
> Yes, even an implicit conversion to bool could be useful.
Hrrr, no please no implicit conversion.
After comparing with optional,  the problem could also be what the user
could expect from

expected<bool> b = f();
if (b) {...}
>
>> Do you pretend to provide a C++98 portable implementation?
> I'm pretty sure it's possible with some features disable such as the
> move semantics.
I would not be able to use it if Boost.Move is not supported.
> Should we use boost::variant to facilitate the C++98 variant
> implementation ?
I don't know if boost::variant supports move semantics. I don't think it
is worth adding this dependency, but maybe I'm wrong.
>
>> How the expected_or_error behaves in the presence of copy constructor
>> exceptions?
> It doesn't capture the exception and the responsibility of handling
> this exception is delegated to higher layer.

Stating clearly this behavior in the proposal would be appreciated.

>
>> Which expected_or_error<> functions can be declared as noexcept?
>
> Constructor/operator=: noexcept if the T/ErrorType copy/move
> constructor doesn't throw.
> Destructor: noexcept if the T/ErrorType destructor doesn't throw.
> Swap: noexcept if the move constructor(c++11)/ copy constructor(c++98)
> doesn't throw.
>
> Observer and getter can be declared as no except.
>
>> Which expected<> functions can be declared as noexcept?
>>
> Same as above plus:
>
> noexcept:
> fromException(std::exception_ptr p);
> fromException();
> fromCode(F fun);
>
Could you add them to the scope of the proposal,
BTW, could you rename the camelCase function to the usual Boost style,
e.g. from_exception. Note that I have removed these functions and
replaced them as non-member factories.
What do you think?

>> Best,
>> Vicente
>>
> Your questions are interesting and I'm not sure I gave the best answers.
> Some of the design decisions are hard to guess without any feedback
> from users (such as the value semantics).
>
> I like your implementation of expected, the "then" method is similar
> to what I tried to achieve with "resolve".
> Maybe we could have a method "otherwise" which do the same than "then"
> but with the error ?
Yes sure. It would be great to explore it with specific examples.
>
> I'll send soon my proposal to the boost mailing-list for any
> reviews/comments.
>


Great,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
On 04/20/2013 03:14 PM, Vicente J. Botet Escriba wrote:

> Le 20/04/13 14:44, Pierre T. a écrit :
>> On 04/20/2013 11:36 AM, Vicente J. Botet Escriba wrote:
>>> Le 20/04/13 10:50, Vicente J. Botet Escriba a écrit :
>>>> Le 19/04/13 16:36, Pierre T. a écrit :
>>>>> On 04/13/2013 12:57 PM, Klaim - Joël Lamotte wrote:
>>>>>> On Sat, Apr 13, 2013 at 8:38 AM, Pierre T. <[hidden email]>
>>>>>> wrote:
>>>>>>
>>>>>>
>>>>> Hello,
>>>>>
>>>>> I gave a try at the implementation of the expected_or_error class.
>>>>> I used the boost layout to package the implementation, you can
>>>>> download it here : http://www.hyc.io/boost/expected.zip
>>>>> Finally, feel free to explore the documentation I wrote
>>>>> http://www.hyc.io/boost/index.html
>>>>>
>>>>> Please, do not hesitate to give me advices and critics to improve
>>>>> this library and my future proposal.
>>>>>
>>>>>
>>>> Hi,
>>>>
>>>> glad to see you are exploring the different alternatives. This is
>>>> really a good starting point.
>>>>
>>>> Now it is time to make a concrete proposal for you candidature.
>>>>
>>>>
>>>
>>> Hi again,
>>>
>> Hi,
>>> I have some questions:
>>>
>>> Do you think that expected and/or expected_or_error could/should
>>> have value semantics, that is define operator==?
>> I don't have any use cases where expected/expected_or_error would
>> have value semantics.
>> Even if the underlying value has value semantics, you can't compare
>> exceptions and you rarely compare two error code encapsulated into
>> two variables (of course you often compare a variable and a constant
>> error code).
>> So, unless we give me good arguments, I would consider it as entity
>> semantics.
> I was wondering as optional<T> has value semantics and no value is
> different from any optional valued. I don't know yet if it has a sens
> to define it for expected_or_error and you are right we need a valid
> use case.
Do you say there is a sens to define it for expected ? How do we compare
two exceptions ?

>>
>>> I don't know if the const get function should be provided?
>>>   const T& get() const { return value; }
>>> what do you think?
>> Because expected<> aims to always be a return value, I would be say
>> we don't need it.
>> Nevertheless, the user could pass expected to a function by
>> const-ref. So to enable any programming style, I would let it there.
> Sorry, I meant the non-const. Anyway, I guess that it is there to make
> easier to pass a non-const to a function expecting a T&.
>
> expected<T> r =f();
> g(r.get());
>>
>>>
>>> What about an explicit conversion to the underlying type that
>>> behaves as the get function?
>> Is there really an interest to do (type)e instead of e.get() ? I'm
>> not sure. However I don't have any arguments against it.
>>
>>> What about an explicit conversion to bool that behaves as the valid
>>> function?
>> Yes, even an implicit conversion to bool could be useful.
> Hrrr, no please no implicit conversion.
> After comparing with optional,  the problem could also be what the
> user could expect from
>
> expected<bool> b = f();
> if (b) {...}
Right !

>>
>>> Do you pretend to provide a C++98 portable implementation?
>> I'm pretty sure it's possible with some features disable such as the
>> move semantics.
> I would not be able to use it if Boost.Move is not supported.
>> Should we use boost::variant to facilitate the C++98 variant
>> implementation ?
> I don't know if boost::variant supports move semantics. I don't think
> it is worth adding this dependency, but maybe I'm wrong.
>>
>>> How the expected_or_error behaves in the presence of copy
>>> constructor exceptions?
>> It doesn't capture the exception and the responsibility of handling
>> this exception is delegated to higher layer.
>
> Stating clearly this behavior in the proposal would be appreciated.
In fact, we could create an error code class containing a ptr_exception.
I'm not really sure what would be the best. Though, I'd stick to the
first idea at the moment.

>>
>>> Which expected_or_error<> functions can be declared as noexcept?
>>
>> Constructor/operator=: noexcept if the T/ErrorType copy/move
>> constructor doesn't throw.
>> Destructor: noexcept if the T/ErrorType destructor doesn't throw.
>> Swap: noexcept if the move constructor(c++11)/ copy
>> constructor(c++98) doesn't throw.
>>
>> Observer and getter can be declared as no except.
>>
>>> Which expected<> functions can be declared as noexcept?
>>>
>> Same as above plus:
>>
>> noexcept:
>> fromException(std::exception_ptr p);
>> fromException();
>> fromCode(F fun);
>>
> Could you add them to the scope of the proposal,
> BTW, could you rename the camelCase function to the usual Boost style,
> e.g. from_exception. Note that I have removed these functions and
> replaced them as non-member factories.
> What do you think?
>
It's an idea that I really like in your implementation, I prefer the
"make_XXX" non-member function. So I'm totally agree with this idea.

>>> Best,
>>> Vicente
>>>
>> Your questions are interesting and I'm not sure I gave the best answers.
>> Some of the design decisions are hard to guess without any feedback
>> from users (such as the value semantics).
>>
>> I like your implementation of expected, the "then" method is similar
>> to what I tried to achieve with "resolve".
>> Maybe we could have a method "otherwise" which do the same than
>> "then" but with the error ?
> Yes sure. It would be great to explore it with specific examples.
I'll add a "otherwise" method in the proposal.
>>
>> I'll send soon my proposal to the boost mailing-list for any
>> reviews/comments.
>>
>
>
> Great,
> Vicente

Thanks for all the comments !

Pierre T.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Vicente Botet
Le 20/04/13 20:45, Pierre T. a écrit :

> On 04/20/2013 03:14 PM, Vicente J. Botet Escriba wrote:
>> Le 20/04/13 14:44, Pierre T. a écrit :
>>> On 04/20/2013 11:36 AM, Vicente J. Botet Escriba wrote:
>>>> Do you think that expected and/or expected_or_error could/should
>>>> have value semantics, that is define operator==?
>>> I don't have any use cases where expected/expected_or_error would
>>> have value semantics.
>>> Even if the underlying value has value semantics, you can't compare
>>> exceptions and you rarely compare two error code encapsulated into
>>> two variables (of course you often compare a variable and a constant
>>> error code).
>>> So, unless we give me good arguments, I would consider it as entity
>>> semantics.
>> I was wondering as optional<T> has value semantics and no value is
>> different from any optional valued. I don't know yet if it has a sens
>> to define it for expected_or_error and you are right we need a valid
>> use case.
> Do you say there is a sens to define it for expected ? How do we
> compare two exceptions ?
I don't know. We could consider that the exception is not part of the
expected class in the same way as we don't take in account an internal
mutex when we compare 2 synchronized_value.
Comparing two valued expected would rely on the type T, comparing to
exceptional expected succeeds always (as if the value was not set) and
mixing them fails. The main difference is that here the exception could
be visible while in synchronized_value the mutex is hidden.

Let comparison out of the scope of the proposal for the time been.

Best,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Pierre Talbot-2
On 04/21/2013 09:17 AM, Vicente J. Botet Escriba wrote:

> Le 20/04/13 20:45, Pierre T. a écrit :
>> On 04/20/2013 03:14 PM, Vicente J. Botet Escriba wrote:
>>> Le 20/04/13 14:44, Pierre T. a écrit :
>>>> On 04/20/2013 11:36 AM, Vicente J. Botet Escriba wrote:
>>>>> Do you think that expected and/or expected_or_error could/should
>>>>> have value semantics, that is define operator==?
>>>> I don't have any use cases where expected/expected_or_error would
>>>> have value semantics.
>>>> Even if the underlying value has value semantics, you can't compare
>>>> exceptions and you rarely compare two error code encapsulated into
>>>> two variables (of course you often compare a variable and a
>>>> constant error code).
>>>> So, unless we give me good arguments, I would consider it as entity
>>>> semantics.
>>> I was wondering as optional<T> has value semantics and no value is
>>> different from any optional valued. I don't know yet if it has a
>>> sens to define it for expected_or_error and you are right we need a
>>> valid use case.
>> Do you say there is a sens to define it for expected ? How do we
>> compare two exceptions ?
> I don't know. We could consider that the exception is not part of the
> expected class in the same way as we don't take in account an internal
> mutex when we compare 2 synchronized_value.
> Comparing two valued expected would rely on the type T, comparing to
> exceptional expected succeeds always (as if the value was not set) and
> mixing them fails. The main difference is that here the exception
> could be visible while in synchronized_value the mutex is hidden.
>
> Let comparison out of the scope of the proposal for the time been.
>
> Best,
> Vicente
>
I think this behavior could lead to potential mis-understanding (and
possibly bugs ?) from the user. However, you are right, we'll discuss it
later if needed.

Best regards,
Pierre T.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [gsoc-2013] Boost.Expected

Gottlob Frege
A few thoughts about expected<> :


I think comparison with optional<> is worthwhile.  In fact, I think we
should consider small changes to optional, if necessary, if it helps them
align.  Specifically I'm thinking of the cast to bool.  Does the below
conversions to bool bother anyone?


std::expected<int, Err> exp = ...;
std::optional<int> opt = ...;

if (opt) {
...
}

if (exp) {
...
}

And if that doesn't bother you, change the 'int' to 'bool' above.

I don't care which way it goes (the alternative being a explicit function
call, like exp.valid() or is_valid() or...), but I think it makes sense for
expected and optional to work the same way, and currently, optional<> is
set to work in the above. So if you really dislike if (exp), then you have
an uphill battle to change optional, which was just accepted.


As for comparing "exceptions", I'm not sure the exception part of expected
should be always considered an exception.  Maybe it is just the "false
case" type.  ie

expected<true_case, false_case>
or
expected<expect_type, else_type>

or however you want to think of it.

I would only call it an *exception* type if it gets thrown when trying to
access the value of a false expected:


std::expected<int, Exception> exp;

int x = exp.value(); // has no value - does this throw bad_expected_access,
or does it throw Exception()?


I think answering these questions might help answering the comparison
questions.  ie first know what expected<> really is.

Tony

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
1234