Date: Sat, 3 Oct 2020 20:28:39 +0100
*> One of these things is not like the other. The treatment of
the predicate is *backwards* in `count_until`.*
Why is that a problem? If I had accidentally named it "*count_while*" then
that'd be a mistake to correct but it says "_*until*". They are two
different functions that count elements. As long as the name lines up with
what they do I don't see a problem. I welcome other suggestions btw. To me,
it's greenlit as long as it makes sense at the call site where I have to
figure out what the line I'm looking at does.
*_at_Giuseppe* Thanks for the last example. That's the point I was trying to
make, selling this to more C-style oriented programmers as a bridge. You
can call this 1 function to replace your for loops if you treat the return
value as an index. Any sign of extra complexity (ranges, tuples, ...) is
going to be met by "*Ugh, that sounds complicated, I'll stick to the for
loop*" and there won't be any progress on that front. I tried it too many
times to believe that we are past this bump. In terms of its place in the
std library, it's just a function that counts container elements until
something says true. It does not imply you should avoid iterators or ranges
like Jason suggests it does.
About the points you raise:
1. Yes, that's why I had the first version using size_t, which I still
think is better for the signed / unsigned reason you mention. That should
be changed back.
2. The return value for "no match found" would be v.size() in the amended
version, so
auto i = std::count_until(v.begin(), v.end(), [](const auto& e) { return
e.abc == 2; });
if (i < v.size())
{
std::cout << "Found match at " << i << std::endl;
}
(i < v.size()) is the standard index bounds check and that's a big plus.
The only hurdle for a more C-style programmer is accepting 1 lambda. It
already makes the code less error-prone than a for-loop and can be
refactored to iterators / ranges easily as the C-style API is phased out.
An immediate profit with a gentle-cycle refactor.
3. / 4. Like I said, the function should not imply index semantics. It's
only concern is counting elements. If the user has reasonable concern that
the target container might be refactored into something where indices don't
make sense, the user can put a static_assert into the code and catch it at
compile time. Which leads into point 4. It's not going to help make
guarantees along those lines. The responsibility for correctness ends with
returning the correct count value. If I could amend the title of this
thread I would drop the word index. Using the return value as an index
should be incidental as far as the standard library is concerned. That's
easier to defend.
On Sat, 3 Oct 2020 at 18:04, Giuseppe D'Angelo via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Il 03/10/20 17:46, Jason McKesson via Std-Proposals ha scritto:
> > And they can do the exact same thing with the `enumerate` view
> > version. We already have the tool in our toolbelt, so why do we need a
> > very slightly shorter version of it?
>
> Is it really "slightly shorter"? At least as a mental exercise, getting
> an index shouldn't require creating a zipped view of elements and
> indices, applying a projection to get just the element, applying a
> predicate to that projection, find the first that matches, extract the
> index from the pair and return it (plus figuring out how to signal "not
> found")...
>
> Thanks,
> --
> Giuseppe D'Angelo | giuseppe.dangelo_at_[hidden] | Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company
> Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
> KDAB - The Qt, C++ and OpenGL Experts
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
the predicate is *backwards* in `count_until`.*
Why is that a problem? If I had accidentally named it "*count_while*" then
that'd be a mistake to correct but it says "_*until*". They are two
different functions that count elements. As long as the name lines up with
what they do I don't see a problem. I welcome other suggestions btw. To me,
it's greenlit as long as it makes sense at the call site where I have to
figure out what the line I'm looking at does.
*_at_Giuseppe* Thanks for the last example. That's the point I was trying to
make, selling this to more C-style oriented programmers as a bridge. You
can call this 1 function to replace your for loops if you treat the return
value as an index. Any sign of extra complexity (ranges, tuples, ...) is
going to be met by "*Ugh, that sounds complicated, I'll stick to the for
loop*" and there won't be any progress on that front. I tried it too many
times to believe that we are past this bump. In terms of its place in the
std library, it's just a function that counts container elements until
something says true. It does not imply you should avoid iterators or ranges
like Jason suggests it does.
About the points you raise:
1. Yes, that's why I had the first version using size_t, which I still
think is better for the signed / unsigned reason you mention. That should
be changed back.
2. The return value for "no match found" would be v.size() in the amended
version, so
auto i = std::count_until(v.begin(), v.end(), [](const auto& e) { return
e.abc == 2; });
if (i < v.size())
{
std::cout << "Found match at " << i << std::endl;
}
(i < v.size()) is the standard index bounds check and that's a big plus.
The only hurdle for a more C-style programmer is accepting 1 lambda. It
already makes the code less error-prone than a for-loop and can be
refactored to iterators / ranges easily as the C-style API is phased out.
An immediate profit with a gentle-cycle refactor.
3. / 4. Like I said, the function should not imply index semantics. It's
only concern is counting elements. If the user has reasonable concern that
the target container might be refactored into something where indices don't
make sense, the user can put a static_assert into the code and catch it at
compile time. Which leads into point 4. It's not going to help make
guarantees along those lines. The responsibility for correctness ends with
returning the correct count value. If I could amend the title of this
thread I would drop the word index. Using the return value as an index
should be incidental as far as the standard library is concerned. That's
easier to defend.
On Sat, 3 Oct 2020 at 18:04, Giuseppe D'Angelo via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Il 03/10/20 17:46, Jason McKesson via Std-Proposals ha scritto:
> > And they can do the exact same thing with the `enumerate` view
> > version. We already have the tool in our toolbelt, so why do we need a
> > very slightly shorter version of it?
>
> Is it really "slightly shorter"? At least as a mental exercise, getting
> an index shouldn't require creating a zipped view of elements and
> indices, applying a projection to get just the element, applying a
> predicate to that projection, find the first that matches, extract the
> index from the pair and return it (plus figuring out how to signal "not
> found")...
>
> Thanks,
> --
> Giuseppe D'Angelo | giuseppe.dangelo_at_[hidden] | Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company
> Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
> KDAB - The Qt, C++ and OpenGL Experts
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2020-10-03 14:28:53