[outcome] expected, etc. why are these assignable

It just occurred to me that for a similar component I created some time ago for my own purposes, I (intentionally?) support of the assignment operator. Copy construction was permitted however. So the only way to use the component is: checked_result<int> = function(...); something void function(checked_result & cr, ....) will be the same as void function(const checked_result & cr, ...) because checked_result only contains const functions. That is, once constructed, it's immutable. Personally I never use an interface which passes a mutable type to a function. To me it violates the mathematical idea of what a function is. Doesn't this simplify things? Doesn't this eliminate the whole questions about about empty state, etc. Doesn't this better model the "mondad" concept we're trying to leverage on. And why the hell are we modifying and an object designed to model a result in the first place? It doesn't make logical sense in terms of we expect a "result" to be. I plunk down my money (a function) and ask for a pepperoni pizza. Either they say they don't have pepperoni and give me my money back or give me a pizza. I don't think of modifying this result - it's an artifact of history. And wouldn't making these things immutable, eliminate a large part of the whole controversy? Just a thought. I think sometimes something is hard because we haven't thought enough about what we're really trying to do - what problem we're trying to solve. Robert Ramey

Robert Ramey wrote:
And wouldn't making these things immutable, eliminate a large part of the whole controversy?
An immutable result/outcome would have no default constructor (because it's
default-constructed only in cases you need to put the value into it later)
which would eliminate the motivation for an empty state as something into
which to default-construct... but that's only a small part of the whole
controversy.
Niall's argument for empty state does not rest entirely on default
construction. He argues that it makes Outcome a four-state variant instead
of a tri-state one and having the fourth state is useful in certain
scenarios when the function that returns it has a legitimate need to report
four states.
That is, he wants to be able to express this:
enum class no_difference
{
_
}
expected

Andrzej Krzemienski wrote:
Or you could use expected

Now with some preliminary documentation: https://github.com/pdimov/variant2/blob/develop/doc/expected.md

On 6/2/17 8:42 AM, Peter Dimov via Boost wrote:
Right - so it would only eliminate a small part of the whole controversy.
OK - I guess then that "expected" wouldn't be consistent with my
expectations for a function result - which for me is the main (or only)
use case. In my world, I would expect
template
Hmmm - maybe states and parameters are getting confused. An "Escape" parameter can contain an arbitrary number of states in one parameter. Robert Ramey

Forgive me chiming in late, but what is the semantic difference between:
enum class no_difference
{
_
}
expected

Richard Hodges wrote:
There are various ways to represent the same four-state variant
syntactically, and the main difference is in, well, syntax, when referring
to it. You could, for example, use
outcome

On 2 June 2017 at 18:43, Peter Dimov via Boost

On 6/2/17 9:22 AM, Richard Hodges via Boost wrote:
Right. By leaving the second parameter E as a template parameter, it can contain as much state or as little state as one wants. Your formulation might be considered more heavy weight - but hey, that's up to the user - not us. Robert Ramey

On 02/06/2017 16:42, Peter Dimov via Boost wrote:
Nearly correct, but not quite. My argument in favour of an emoty state is because the implementation will implement an empty state internally anyway, so either you expose that publicly, or you don't. It's no difference for the implementation. You then list the use cases for a formal public empty state, and on balance I came out in favour. During the review quite a few people came to the same conclusion: on balance, it's better than the alternatives. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

Niall Douglas wrote:
The same argument has been used in variant's case and the initial proposal did include a bona fide empty state. It was however swept under the carpet because never-empty, or even the illusion of never-empty, as in the case of C++17's variant, was found preferable. It's true that the implementation will have an empty state internally as an implementation detail, but it need not be user-visible. The argument for never having an empty state, in variant's case, is that having an empty state makes people who don't use it pay for it in more complex code that has to check for empty because visit, for example, has to handle all alternatives. It's better, there, to make the default never empty. People who want an empty state can always put an empty alternative in the list.

2017-06-02 17:17 GMT+02:00 Robert Ramey via Boost
The consumer of the `outcome` could just observe the state. But the producer may have legitimate reasons to change the value of `outcome` objects when preparing its final value. Also, some use cases require being able to store outcomes in containers. I guess design would be easier if we could see all use cases listed. Regards, &rzej;

On 6/2/17 8:53 AM, Andrzej Krzemienski via Boost wrote:
2017-06-02 17:17 GMT+02:00 Robert Ramey via Boost
:
That is exactly what I'm questioning. I'm suggesting that changing the value of a "result" is indication of a fundamental mis-understanding what a "result" is. I'm suggesting that requiring that "expected" be immutable will actually improve it's conceptual power for users. It require them to use a more suitable type when "expected" is not suitable. Of course I'm guilty of speculating myself here. I'm questioning the premise "component X is useful, but it would be more useful if ....". Maybe we should keep simple things simple. BTW TL;DR; - I'm coming to the opinion that the usage of immutable objects is a key attribute of the functional programming ala haskel and that perhaps we should think about this more when we design stuff.
Also, some use cases require being able to store outcomes in container
LOL - I can't prove it, but this sounds like a very bad idea to me. But it also raises an entirely different issue. The requirement of default constructors for container elements is an artifact of the way containers are implemented. So here, an implementation artifact is bleeding over to the abstract conceptual design of the element. This is recipe for brain soup.
I guess design would be easier if we could see all use cases listed.
Ahhh - the pitfalls when designing on speculation about the future. Mix in design by committee and you've got ... gridlock. The discussions are interesting, but when they evolve into communal design from a simple review things get ... complicated. Maybe if we kept reviews more focused on thumbs up/down and criticism and support rather than "design" they might be less of a death march and we might encourage more people to participate in reviews. Robert Ramey

I gave many examples throughout the review of changing the state of
existing outcomes. Indeed, almost every AFIO object init function
implementation does so, we construct an empty or valued result<T> on the
stack and fill it in over time as part of the "two phase construction"
used throughout AFIO.
Also, in KernelTest, there is some constexpr code which statically
constructs a std::array
participants (6)
-
Andrzej Krzemienski
-
Niall Douglas
-
Peter Dimov
-
Richard Hodges
-
Robert Ramey
-
Vicente J. Botet Escriba