C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Fwd: ranges::collect

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Fri, 27 Sep 2024 17:06:07 -0400
On Thu, Sep 26, 2024 at 5:07 PM Corentin Adam via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> I hadn't thought of it that way, but I agree with you that it would work
> too.
> If I understand correctly, you mean some range constructors like this
> <https://godbolt.org/z/KGvaGboG7>?
>

Presumably more like this <https://godbolt.org/z/Tbe1jcvEr>. (The only diff
is the addition of `from_range_t`.)

IIUC, the proposal is to take a range of optionals and collapse it into an
optional of range, with this signature and semantics (if not this exact
name):

std::optional<std::vector<T>> when_all(std::vector<std::optional<T>> v) {
if (std::ranges::all_of(v, [](auto&& x) { return bool(x); })) {
return v | std::views::transform([](auto&& o) { return *o; }) |
std::ranges::to<std::vector<T>>();
} else {
return std::nullopt;
}
}

The obvious next step after `when_all` is `when_any`:

std::optional<T> when_any(std::vector<std::optional<T>> v) {
auto it = std::ranges::find(v, true);
return (it == v.end()) ? *it : std::nullopt;
}

Now, I don't think either of these is suitable for `ranges::to`, because
then what would happen when I write `std::ranges::to<std::optional>()`?
Just specifying the *shape of the output* isn't sufficient to tell me (as
the code-writer or as the code-reader/reviewer) what *algorithm* I want (or
expect) to be used to get the data into that shape. When the algorithm is
non-obvious, and/or when there's more than one possible algorithm that
could be used, the Standard Library should explicitly name the algorithm.


Coincidentally, it was noted on the cpplang Slack just a day or two ago that
    // https://godbolt.org/z/1a6xcohTn
    char hello[] = "hello";
    auto s1 = hello | std::ranges::to<std::string>();
    auto s2 = hello | std::views::all | std::ranges::to<std::string>();
    assert(s1 != s2);
which is kind of another case of "when there's multiple possible ways to do
a transformation, it's confusing to give them all the same name."

–Arthur



On Thu, Sep 26, 2024 at 5:07 PM Corentin Adam via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> I hadn't thought of it that way, but I agree with you that it would work
> too.
> If I understand correctly, you mean some range constructors like this
> <https://godbolt.org/z/KGvaGboG7>?
>
> I've searched through the current proposals and it seems to me that these
> constructors haven't been proposed yet (even in the optional range
> support proposal), have they?
> If they haven't yet been proposed, what do you think about drafting a
> proposal to include them?
>
> Another question, why favor the constructor from ranges approach over the
> collect free function approach?
>
> Le mer. 11 sept. 2024 à 19:47, Barry Revzin <barry.revzin_at_[hidden]> a
> écrit :
>
>> On Wed, Sep 11, 2024, 11:56 AM Corentin Adam via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>>
>>> I've recently been working on a cpp implementation of the rust collect
>>> function: :
>>> https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect.
>>>
>>> This function has two main uses in rust:
>>> * construct containers from ranges (exactly the work achieved by
>>> std::ranges::to)
>>> * collect ranges of expected/optional values into expected/optional
>>> range of value. Thus, if all values in the range are correct (in other
>>> words has_value() == true), the return value is true and contains the range
>>> of underlying values. Otherwise, the return value contains the first error
>>> encountered in the range.
>>>
>>
>> ranges::to can support the second use-case as well. We just need to add
>> the appropriate constructor to optional and expected.
>>
>> Barry
>>
>>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-09-27 21:06:22