Hello,
I looked at the review, at the code and some time ago I tried
to implement my own variant. In my opinion in variant2 the
individual parts are more worth than the whole. Most
implementation details would be of great use for implementing
variants with a differnt trade-off. Hence the library ought
to be split into several independend parts:
* a typing switch
* a variadic union
* an extendable visitation mechanism
* a variant view
* related type traits
* several implementation of a concrete variant
1. A typing switch
The typing switch would be provide a litle bit more than (and
can be implementated with help of) mp_with_index.
The following pseudo code shows the implementation idea:
template
Jan Herrmann wrote:
I looked at the review, at the code and some time ago I tried to implement my own variant. In my opinion in variant2 the individual parts are more worth than the whole. Most implementation details would be of great use for implementing variants with a differnt trade-off. Hence the library ought to be split into several independend parts: * a typing switch * a variadic union * an extendable visitation mechanism * a variant view * related type traits * several implementation of a concrete variant
and Robert Ramey wrote:
I'm way out of my depth in the variant discussion. Seems to me it revolves around all the trade offs regarding design choices. Could we perhaps decide not to decide. Suppose we create a type which looks like:
template< bool BasicGuaranteeSupported, bool StrongGuaranteeSupported, bool EmptyStateProhibited, bool AssignmentSupported, bool MoveSupported, class T ...
struct mother_of_variants{ // some trivial mp11 code };
and in my review I wrote:
Ideally, perhaps a Boost.Variants *library* should provide a selection of different variants with different features?
I believe it's not reasonable or realistic to ask Peter to refactor his code to the extent that e.g. Robert suggests. But it would be good, as Jan suggests, to make it easier to build alternative variants by re-using the "uncontroversial" parts of the Variant2 code. Peter, what do you think about this? I'm not suggesting that you explicitly make the various internal components (as listed by Jan) public interfaces, with docs etc., but just add enough comments for others to be able to work with it and perhaps break it into multiple files. A quick example of how to build, say, a trivial variant with single storage that rejects assignment of types that might throw, would make it perfect! Regards, Phil.
On Tue, Apr 16, 2019 at 9:47 AM Phil Endecott via Boost < boost@lists.boost.org> wrote:
Jan Herrmann wrote:
I looked at the review, at the code and some time ago I tried to implement my own variant. In my opinion in variant2 the individual parts are more worth than the whole. Most implementation details would be of great use for implementing variants with a differnt trade-off. Hence the library ought to be split into several independend parts: * a typing switch * a variadic union * an extendable visitation mechanism * a variant view * related type traits * several implementation of a concrete variant
and Robert Ramey wrote:
I'm way out of my depth in the variant discussion. Seems to me it revolves around all the trade offs regarding design choices. Could we perhaps decide not to decide. Suppose we create a type which looks like:
template< bool BasicGuaranteeSupported, bool StrongGuaranteeSupported, bool EmptyStateProhibited, bool AssignmentSupported, bool MoveSupported, class T ...
struct mother_of_variants{ // some trivial mp11 code };
and in my review I wrote:
Ideally, perhaps a Boost.Variants *library* should provide a selection of different variants with different features?
I believe it's not reasonable or realistic to ask Peter to refactor his
code
to the extent that e.g. Robert suggests. But it would be good, as Jan suggests, to make it easier to build alternative variants by re-using the "uncontroversial" parts of the Variant2 code. Peter, what do you think about this? I'm not suggesting that you explicitly make the various internal components (as listed by Jan) public interfaces, with docs etc., but just add enough comments for others to be able to work with it and perhaps break it into multiple files. A quick example of how to build, say, a trivial variant with single storage that rejects assignment of types that might throw, would make it perfect!
This is the policy-based design approach. It happens when the expert is so uncertain in the most critical design choices that he concludes that leaving them to the casual user is a better bet for correctness; or when a committee demands customization as a condition for acceptance.
On 4/16/19 10:56 AM, Emil Dotchevski via Boost wrote:
On Tue, Apr 16, 2019 at 9:47 AM Phil Endecott via Boost < boost@lists.boost.org> wrote:
Jan Herrmann wrote:
I looked at the review, at the code and some time ago I tried to implement my own variant. In my opinion in variant2 the individual parts are more worth than the whole. Most implementation details would be of great use for implementing variants with a differnt trade-off. Hence the library ought to be split into several independend parts: * a typing switch * a variadic union * an extendable visitation mechanism * a variant view * related type traits * several implementation of a concrete variant
and Robert Ramey wrote:
I'm way out of my depth in the variant discussion. Seems to me it revolves around all the trade offs regarding design choices. Could we perhaps decide not to decide. Suppose we create a type which looks like:
template< bool BasicGuaranteeSupported, bool StrongGuaranteeSupported, bool EmptyStateProhibited, bool AssignmentSupported, bool MoveSupported, class T ...
struct mother_of_variants{ // some trivial mp11 code };
and in my review I wrote:
Ideally, perhaps a Boost.Variants *library* should provide a selection of different variants with different features?
I believe it's not reasonable or realistic to ask Peter to refactor his
code
to the extent that e.g. Robert suggests. But it would be good, as Jan suggests, to make it easier to build alternative variants by re-using the "uncontroversial" parts of the Variant2 code. Peter, what do you think about this? I'm not suggesting that you explicitly make the various internal components (as listed by Jan) public interfaces, with docs etc., but just add enough comments for others to be able to work with it and perhaps break it into multiple files. A quick example of how to build, say, a trivial variant with single storage that rejects assignment of types that might throw, would make it perfect!
This is the policy-based design approach. Right
It happens when the expert is so uncertain in the most critical design choices Right - when concensus on design choices cannot be reached.
leaving them to the casual user is a better bet for correctness; Hmmm - not sure I'm buying that. or when a committee demands customization as a condition for acceptance. Right. Sometimes this is a disaster - C++ intialization and probably Modules and Contracts too. But sometimes it can work out very well. It's widely explored in Alexandrescu's seminal book "Modern C++ Design". I've been happy with the way it has worked out in safe numerics. I
that he concludes that think boost.iterators is an example and I think there are others. Of course there are disasters also. I would disagree that the only alternative is to leave them to the "casual user". There is no reason that a library cannot define the common cases for the "casual user" and still expose the the base functionality as an "escape hatch" for those of us who are masochists. I see this is really a "simple" issue of implementation. Is it less work to factor out the commonality of all these types or build each one individually from scratch? The only way to know is to actually attempt it. Of course bringing this up at the end of 3 weeks of intense review is ... inconvenient. But it's only that review which reveals the problems we have with the one by one approach. Of course this is really unfair to the library author. I don't think there's any way to get around that and I don't have an answer. But knowing something of the personalities of many the characters involved, some part of me is thinking that peter, obsessive intellectual exhibitionist that he is, is already experimenting with idea to see whether i might be incorporated or just needs to be killed off. Robert Ramey
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Tue, Apr 16, 2019 at 11:36 AM Robert Ramey via Boost < boost@lists.boost.org> wrote:
It happens when the expert is so uncertain in the most critical design choices Right - when concensus on design choices cannot be reached.
Consensus is important only insofar as it is believed to lead to correct design, but sometimes correctness and consensus differ. Correctness is what matters.
On 4/16/19 11:55 AM, Emil Dotchevski via Boost wrote:
On Tue, Apr 16, 2019 at 11:36 AM Robert Ramey via Boost < boost@lists.boost.org> wrote:
It happens when the expert is so uncertain in the most critical design choices Right - when concensus on design choices cannot be reached.
Consensus is important only insofar as it is believed to lead to correct design, but sometimes correctness and consensus differ. Correctness is what matters.
Hmmm - the problem is that there often multiple "correct" designs. That is, none can be proved to be "incorrect" in every context. The notion of "correctness" is context sensitive. One person might define having an empty state as "incorrect" while another might have another definition. The problem here isn't making a "correct" design, it's agreeing on what is "correct" Robert Ramey
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
wt., 16 kwi 2019 o 22:02 Robert Ramey via Boost
On 4/16/19 11:55 AM, Emil Dotchevski via Boost wrote:
On Tue, Apr 16, 2019 at 11:36 AM Robert Ramey via Boost < boost@lists.boost.org> wrote:
It happens when the expert is so uncertain in the most critical design choices Right - when concensus on design choices cannot be reached.
Consensus is important only insofar as it is believed to lead to correct design, but sometimes correctness and consensus differ. Correctness is what matters.
Hmmm - the problem is that there often multiple "correct" designs. That is, none can be proved to be "incorrect" in every context. The notion of "correctness" is context sensitive. One person might define having an empty state as "incorrect" while another might have another definition. The problem here isn't making a "correct" design, it's agreeing on what is "correct"
Yes, I think policies reflect tat there exist different design trade-offs: and one trade-off may be ideal for one group of people and the worse possible choice for other people. Sometimes, if we are lucky, one trade-off serves a great majority of users, so we can forget the policies. Sometimes not, and then we either a number of similar types, or consider policies. This has little to do with correctness. In case of variant, we can think of the following (all correct) ways of guaranteeing no run-time surprise upon failed assignment in the case of nasty types: - double buffer with second buffer on the heap (spatial optimization, in case assignments are rare) - double buffer with second buffer inside variant (predictable time guarantee) - fail to compile the assignment (no spacial cost is payed for users that use functional-programming style) Either of these choices is correct and may be considered best for a given group of people. By this, I do not mean that adding policies is necessarily a good way to go. Having many types that do almost the same thing (whether they are instantiated from templates or defined manually) is a problem in itself. Regards, &rzej;
Phil Endecott wrote:
I believe it's not reasonable or realistic to ask Peter to refactor his code to the extent that e.g. Robert suggests. But it would be good, as Jan suggests, to make it easier to build alternative variants by re-using the "uncontroversial" parts of the Variant2 code. Peter, what do you think about this? I'm not suggesting that you explicitly make the various internal components (as listed by Jan) public interfaces, with docs etc., but just add enough comments for others to be able to work with it and perhaps break it into multiple files.
Implementation details are just that, implementation details; I prefer to be able to refactor and change them at will, as long as the public interface is unaffected. Encouraging people to use and depend on them is at minimum a commitment that they will not change, and that commitment would very likely need to be backed by unit tests.
Am 16.04.2019 um 20:23 schrieb Peter Dimov via Boost:
Phil Endecott wrote:
I believe it's not reasonable or realistic to ask Peter to refactor his code to the extent that e.g. Robert suggests. But it would be good, as Jan suggests, to make it easier to build alternative variants by re-using the "uncontroversial" parts of the Variant2 code. Peter, what do you think about this? I'm not suggesting that you explicitly make the various internal components (as listed by Jan) public interfaces, with docs etc., but just add enough comments for others to be able to work with it and perhaps break it into multiple files.
Implementation details are just that, implementation details; I prefer to be able to refactor and change them at will, as long as the public interface is unaffected. Encouraging people to use and depend on them is at minimum a commitment that they will not change, and that commitment would very likely need to be backed by unit tests.
Even in cases these implementation details will remain private, unit tests are a good thing do document the internal interface. They show which assertions the author made. In case tests fail it is obvious some of these assertions are vialated. It is good to rethink whether these test are still needed or the change may introduce new bugs. Furthermore in case of maintainer change more (and simple) tests can be useful. In addition I think the basic components will be quite stable and could be part of the public interface to be reused. Regards Jan Herrmann
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Wed, 17 Apr 2019 at 13:38, Jan Herrmann via Boost
... unit tests are a good thing do document the internal interface. They show which assertions the author made.
Yes, let's replace documentation by unit-tests ... documentation is over-rated, no matter what ... degski -- *Microsoft, please kill Paint3D*
Am 17.04.2019 um 15:43 schrieb degski:
On Wed, 17 Apr 2019 at 13:38, Jan Herrmann via Boost
mailto:boost@lists.boost.org> wrote: ... unit tests are a good thing do document the internal interface. They show which assertions the author made.
Yes, let's replace documentation by unit-tests ... documentation is over-rated, no matter what ...
I didn't meant (and wrote) this. My intention is to have additional unit test. They should be written in C++ which means they can be more formal than documentation. They can provide an ADDITIONAL perspective.
degski -- /*/*Microsoft, please kill Paint3D*/*//**/
participants (7)
-
Andrzej Krzemienski
-
degski
-
Emil Dotchevski
-
Jan Herrmann
-
Peter Dimov
-
Phil Endecott
-
Robert Ramey