Date: Mon, 12 Jul 2021 08:54:11 +0200
On 12/07/2021 06.17, Justin Bassett wrote:
> For the remove_nulls, I agree that range_value_t<R> is a better solution, but I didn't write that in the Tony Table for two reasons:
>
> 1. In some functions' contexts, perhaps with a private unconstrained function template, there is no solid guarantee that the range is of optional<T>, so I was trying to capture that sometimes remove_if becomes the cleanest solution.
If the range is not of optional<T>, there is no business talking about nullopt
in the code in the first place.
> 2. range_value_t<R>() or range_value_t<R>(nullopt) are both more "complex". I personally have to pause during reading to figure out what it's doing, whereas reading the remove_if is easy for me, and I was assuming that the average developers---not C++ standard committee members---would probably have a similar response.
>
> I suppose what I'm saying is that even if it's not best practice, I would still expect the remove_if to appear quite often in code, probably after the author was left wondering, "Why can't I just pass in nullopt?". I tend to agree with you that this Tony Table doesn't provide exceedingly strong motivation for this proposal, as we can always use optional<T>() (or computed type name) or smart_ptr<T>() to quite cheaply get the same behavior, but I have yet to be able to come up with better entries.
That latter part lets the feeling grow in me that the proposal is undermotivated.
If there is no convincing situation where the new facility can be used,
maybe that's good information in itself.
Jens
> Thanks,
> Justin
>
> On Sat, Jul 10, 2021 at 12:53 AM Jens Maurer via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> On 10/07/2021 09.18, Justin Bassett via Std-Proposals wrote:
> > I attempted to address these issues in the attached updated draft. It adds many more diffs to the Tony Table, talks about N2478, briefly discusses the odd nature of requiring equality_comparable<U> for equality_comparable_with<T, U>, and includes a few minor changes (adding SG9, uses a hidden friend for the defaulted operator<=>, borrows the wording prior to N2478 for nullptr comparisons).
> >
> > On the Tony Tables: it turns out that without the templates, many of the examples are trivially fixed by converting nullopt -> std::optional<int>() or nullptr -> std::shared_ptr<int>(). With templates, suddenly the information of precisely what optional or what smart_ptr was used becomes hidden, so we have to spend effort to recover that information. So the templates in fact show some cases with a bigger impact. However, even without the templates, it can turn out to be more readable to use the nullfoo variants instead of default constructed types.
>
> What does "alternative is enabled" mean?
>
> In your Tony Table for remove_nulls(nullopt), you assert
> that you have a range of optionals. The lambda passed to
> ranges::remove_if can thus be cleanly replaced by
> ranges::range_value_t<R>() (which ends up as optional<T>()).
> Using this formulation makes the algorithm actually apply
> for both smart pointer and optional uses, because the
> funny nullopt vs. nullptr in the body has been eliminated.
>
> In short, I don't feel the Tony Tables adequately represent
> the best practice in formulating those algorithms, either
> "before" or "after". Given that, the "odd" behavior of
> nullptr and nullopt is maybe actually good, because it forces
> you to write better code for these generic situations.
>
> Please rebase onto the newest working draft, https://wg21.link/std <https://wg21.link/std>
>
> (This might just be an exercise in updating the references.)
>
> Thanks,
> Jens
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden] <mailto:Std-Proposals_at_[hidden]>
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals <https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals>
>
> For the remove_nulls, I agree that range_value_t<R> is a better solution, but I didn't write that in the Tony Table for two reasons:
>
> 1. In some functions' contexts, perhaps with a private unconstrained function template, there is no solid guarantee that the range is of optional<T>, so I was trying to capture that sometimes remove_if becomes the cleanest solution.
If the range is not of optional<T>, there is no business talking about nullopt
in the code in the first place.
> 2. range_value_t<R>() or range_value_t<R>(nullopt) are both more "complex". I personally have to pause during reading to figure out what it's doing, whereas reading the remove_if is easy for me, and I was assuming that the average developers---not C++ standard committee members---would probably have a similar response.
>
> I suppose what I'm saying is that even if it's not best practice, I would still expect the remove_if to appear quite often in code, probably after the author was left wondering, "Why can't I just pass in nullopt?". I tend to agree with you that this Tony Table doesn't provide exceedingly strong motivation for this proposal, as we can always use optional<T>() (or computed type name) or smart_ptr<T>() to quite cheaply get the same behavior, but I have yet to be able to come up with better entries.
That latter part lets the feeling grow in me that the proposal is undermotivated.
If there is no convincing situation where the new facility can be used,
maybe that's good information in itself.
Jens
> Thanks,
> Justin
>
> On Sat, Jul 10, 2021 at 12:53 AM Jens Maurer via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> On 10/07/2021 09.18, Justin Bassett via Std-Proposals wrote:
> > I attempted to address these issues in the attached updated draft. It adds many more diffs to the Tony Table, talks about N2478, briefly discusses the odd nature of requiring equality_comparable<U> for equality_comparable_with<T, U>, and includes a few minor changes (adding SG9, uses a hidden friend for the defaulted operator<=>, borrows the wording prior to N2478 for nullptr comparisons).
> >
> > On the Tony Tables: it turns out that without the templates, many of the examples are trivially fixed by converting nullopt -> std::optional<int>() or nullptr -> std::shared_ptr<int>(). With templates, suddenly the information of precisely what optional or what smart_ptr was used becomes hidden, so we have to spend effort to recover that information. So the templates in fact show some cases with a bigger impact. However, even without the templates, it can turn out to be more readable to use the nullfoo variants instead of default constructed types.
>
> What does "alternative is enabled" mean?
>
> In your Tony Table for remove_nulls(nullopt), you assert
> that you have a range of optionals. The lambda passed to
> ranges::remove_if can thus be cleanly replaced by
> ranges::range_value_t<R>() (which ends up as optional<T>()).
> Using this formulation makes the algorithm actually apply
> for both smart pointer and optional uses, because the
> funny nullopt vs. nullptr in the body has been eliminated.
>
> In short, I don't feel the Tony Tables adequately represent
> the best practice in formulating those algorithms, either
> "before" or "after". Given that, the "odd" behavior of
> nullptr and nullopt is maybe actually good, because it forces
> you to write better code for these generic situations.
>
> Please rebase onto the newest working draft, https://wg21.link/std <https://wg21.link/std>
>
> (This might just be an exercise in updating the references.)
>
> Thanks,
> Jens
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden] <mailto:Std-Proposals_at_[hidden]>
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals <https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals>
>
Received on 2021-07-12 01:54:16