C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Generic code, not the API you are looking for

From: Михаил Найденов <mihailnajdenov_at_[hidden]>
Date: Sat, 10 Sep 2022 16:21:13 +0300
Hello,
I wrote to the author of P2279, but got no response for 10 days now.
As for p2547, I really don't see how it can be improved to address the
issue from this discussion.

I have rewritten the proposal, in particular Problems is completely redone.
Attached is the new draft.

Thank You

On Tue, Aug 30, 2022 at 7:26 PM Sebastian Wittmeier via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hi Mihail,
>
>
>
> if you want to just give directional guidance or you would like to have a
> directional vote, why not contribute to this customization point paper (if
> the author agrees)
>
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2279r0.html
>
> https://github.com/cplusplus/papers/issues/972
>
>
>
> instead of creating a new paper?
>
>
>
> With a special focus, what is missing in
>
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2547r0.pdf
>
> https://github.com/cplusplus/papers/issues/1208
>
> which is finished up for shipping with C++26.
>
>
>
> Best,
>
> Sebastian
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Михаил Найденов via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Di 30.08.2022 17:51
> *Betreff:* Re: [std-proposals] Generic code, not the API you are looking
> for
> *An:* Arthur O‘Dwyer <arthur.j.odwyer_at_[hidden]>;
> *CC:* Михаил Найденов <mihailnajdenov_at_[hidden]>; sotrdg sotrdg via
> Std-Proposals <std-proposals_at_[hidden]>;
>
>
> On Mon, Aug 29, 2022 at 6:32 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
> wrote:
>
> On Sat, Aug 27, 2022 at 11:21 AM Михаил Найденов via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> Hello again,
> I ended up writing a small proposal on this topic as I am quite bothered
> with the issue.
> Attached is the draft
>
>
> Hi Mikhail,
> I looked at your paper. I think it needs to use the words "concept maps"
> somewhere in the paper: that's basically what you're proposing as a
> solution, but the paper doesn't show any evidence that you've dug into the
> previous proposals and why they failed.
>
>
> Hello,
> I am deliberately not providing, or investigating, a solution mainly
> because there is no simple one, much like you explained in Your previous
> post. What is the point discussing concept_maps when we don't have checked
> concepts, concept preservation, nominal conformance?
> The proposal is a top-down view of what I believe is desirable by many -
> to have generic code that works on all/external types and does not require
> effectively a rewrite of the original algorithm and/or extensive planning
> just because it is generic.
>
>
>
> Then, at a higher level, you have not convinced me that there's any
> problem here at all! Your original, "just programming," version of your
> function looks like this (quote):
>
> void silly(string& s) { using char_type = string::char_type; // ... if(s.starts_with("hello")) s.clear(); // ... }
>
> I don't think that code is ordinary "just programming" at all!
> `std::string::char_type` (1) does not exist, and (2) even if it did exist,
> I assume it would be an unnecessarily verbose way of spelling "char". So
> let's eliminate that line. Then, we're left with nicely* generic *code,
> that looks just like classic Stepanov STL code. This function template (or
> "algorithm") can be compiled and works perfectly for any concrete type that
> implements the `starts_with` method (e.g. `string`, `string_view`) and the
> `clear` method (e.g. `string`, `vector`, `deque`, `map`, `set`...)
>
> template<class T>
> void silly(T& t) {
> if (t.starts_with("hello")) t.clear();
> }
>
> Of course in the actual STL there's only the one type (`string`) that
> supports both of those operations. But that's fine, because that's the only
> STL type that can actually be used with this template. If we intended to
> use it with both `string` and `string_view`, we could generalize it a
> little further like this:
>
> template<class T>
> void silly(T& t) {
> if (t.starts_with("hello")) t = T();
> }
>
> But nobody writes templates in a vacuum: there's always some actual
> business purpose behind writing the template. Usually it's to avoid code
> duplication: we have two or more *known* types that satisfy the same
> interface, and so we can write one ("statically polymorphic") version of
> our algorithm using a template like `silly`. The interface and the template
> algorithm generally will evolve cooperatively. For example, the STL is
> designed to facilitate the writing of algorithms that work for any kind of
> STL container, so, all STL containers support the same vocabulary of
> methods: `insert`, `erase`, `begin`, `end`, `T::iterator`, `T::value_type`,
> and so on.
>
>
> I think I will change the example to not be a string or have standard
> operations. This was supposed to be some simple user code, a user class of
> whatever.
>
>
>
>
> It seems to me that you're identifying the problem as "I can't write a
> template that works for *all possible types*, because
> (statically-)polymorphic code implies an interface, and not every possible
> type will implement the interface I require."
>
> But that's not a real-world problem, because in the real world we don't
> write code to work with *every possible type*.
>
> And then, you have an XY problem: you try to get around this artificial
> problem by crufting up your code, turning all your methods into free
> functions and adding a lot of `::`s, and then complain that this makes the
> code uglier. Yes — but that's the "Y" problem! Crufting up the code is
> ugly, but it isn't necessary to solve your "X" problem; and in fact, it's
> not even *sufficient*. In order to use polymorphism (*either* static
> polymorphism with templates, *or* classical runtime polymorphism with
> inheritance), your types must conform to some kind of interface. That's
> both unavoidable and beneficial-to-the-reader.
>
>
> This is not fair. The problem is that we have *two* static polymorphisms
> right now:
> - One is the naive-but-simple "turn it into tparam"
> This one considers the interface as something natural to the type - a type
> having begin(), contains() is a container. Period. Conforming to that
> interface is "hard" - it *has to* come naturally, effectively be
> subclassing.
> - One is (very) advanced
> This one, on the contrary, does not assume the type models the interface -
> it might, it might not, in any case the type must be able to model it...
> any type. Also, exactly because there are no assumptions, the interface
> needs nominal conformance. Conforming is "easy" in the sense it does not
> require subclassing. *However* all the burden is on the original
> developer of the genetic code. Not only a heavy burden, but code change
> requirement as well, a rewrite if not planned for.
>
> Are we OK with that? Is this a natural separation or a language
> limitation? Or may be a natural evolution that highlights a limitation?
> Is the solution polishing the second and still having two systems, or
> overhauling the first to the point it can serve the second as well?
>
>
>
> my $.02,
> Arthur
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-09-10 13:21:26