C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Function overload set type information loss

From: Nathaniel Rupprecht <nathaniel.rupprecht_at_[hidden]>
Date: Wed, 31 Jul 2024 17:42:15 -0400
Another thing, we keep hearing about how we need this proposal because “this isn’t how type theory works,” but this is not true, and is a misunderstanding of both how C++ implements types and of type theory itself.
First off, if you want a really type-theory savvy language, you should probably be using Idris or Haskell or Coq, not C++. But the fundamental misunderstanding seems to be that a template instantiation is a dependently typed function.

```cpp
template<typename T>
int X(int) { /* ...*/ }
```
It is not. The type of any specialization of this “function" is not
 * -> int -> int,
because this is not a function at all, it is a template of how to create a function. For any specialization (e.g. X<int>, X<bool>, etc), the type of the resulting functions is just
 int -> int.

Same with similar functions, even something like
```cpp
template<typename T>
Int X(T y) { /* … */ }
 ```
Things like X<int> and X<double> have type int -> int and double -> int, they are “curried by the compiler,” if you want. So yes, this

int main()
{
   auto f_ptr1= &foo<int, double>;
   auto f_ptr2= &foo<char, double>;
   static_assert(std::is_same_v<decltype(f_ptr1), decltype(f_ptr2)>); // assertion passed.
}

is completely correct. Because foo<int, double> and foo<char, double> both have type () -> (), because they are both functions that take no arguments and return no value. It does not matter how you constructed the function. How you constructed a function is not its type signature. That is just not mathematically true, and it is certainly not true in C++ either.


You are asking for something that does not exist in type theory, you are asking for something like this

F : X -> Y -> Z, a : X
G = F a

to somehow magically result in G not having type Y -> Z (which it clearly, type theoretically does), but have some magical new type
<X> Y -> Z
where the function G “remembers” the “history” of how it was “created” in virtue of it being equal to the currying of another function.

This isn’t a thing.

> On Jul 31, 2024, at 5:23 PM, organicoman via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
>
>
>
> Problem is that you try to break C++ type system.
>
> You suggest:
> ```
> "PFvvE_d" == typeid(f<double>).name()
> ```
>
> And this same by analogy:
>
> ```
> "i_42" == typeid(42).name()
> ```
>
> Nope that's a plain prvalue int. There is no type information lost in the value 42.
>
> Why only template parameters are propagated, not function `f` itself too?
> I even recall that Rust does something like this, each function has
> its own type that is
> inheriting from type based on this function signature
> (thanks this you can still have function pointers).
>
> Besides your suggestion that `auto x` can propagate more than normal
> type and value
> is DoA as it would be breaking change, consider this simple code:
>
> ```
> template<typename T>
> void foo() { }
>
> void foo2() { }
>
> int bar(auto f)
> {
> static int i = 0;
> return ++i;
> }
>
> int main()
> {
> bar(&foo2);
> bar(&foo<int>);
> bar(&foo<double>);
> bar(&foo<float>);
> return bar(&foo<long>);
> }
> ```
>
> It needs to return `5`. And because of this you can't do any magic in
> `bar` to extract additional
>
> It will print 5, there is no type information manipulated inside bar, thus the compiler will stamp the usual code.
>
> information from `f` argument even if the compiler knows it as it
> would be an ODR violation.
>
> The effective type will be used only when the user specify it inside a block scope.
> That way the compiler is notified to track the real type provided by the user, and process the information discrad it after if it proves necessary.
> Type manipulation is the compiler business.
> Value manipulation is the runtime business.
> >
> > On Wed, Jul 31, 2024 at 6:21 AM organicoman via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
> >>
> >>
> >>
> >>
> >>
> >> Sent from my Galaxy
> >>
> >>
> >>
> >> You have been the one who wanted to different types with decltype and effective_decltype.
> >>
> >>
> >>
> >> Why are you complaining?
> >>
> >> The correct answer in your example must be in the following form:
> >>
> >> // one plausible mangled name
> >>
> >> PFvvE_i <--- f<int>
> >>
> >> PFvvE_d <--- f<double>
> >>
> >> the radix PFvvE is the same denoting the same apparent type, and different tags { _i, _d }, to denote the effective type.
> >>
> >> Likewise, the type information is not lost. And you can trace back to what you have called.
> >>
> >>
> >> Anyway, I think we touched everything in this thread, and thanks to you and Tiago i found a corner case, but solved it.
> >>
> >> I think it is time to compile some wording and post it here, maybe it will be more clear.
> >>
> >>
> >> -----Ursprüngliche Nachricht-----
> >> Von: organicoman <organicoman_at_[hidden] <mailto:organicoman_at_[hidden]>>
> >> Gesendet: Mi 31.07.2024 10:50
> >> Betreff: Re: [std-proposals] Function overload set type information loss
> >> An: Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>;
> >> CC: Sebastian Wittmeier <wittmeier_at_[hidden] <mailto:wittmeier_at_[hidden]>>;
> >>
> >>
> >>
> >> With function pointers you can achieve something like; in most cases even this is only possible at runtime:
> >>
> >>
> >>
> >>
> >>
> >> PFvvE <--| do you see the problem here
> >> PFvvE <--| f<int>,f<double>, yet the same name
> >> Just one function f.
> >> Just one function f.
> >> f<double>
> >> f<int>
> >>
> >> In "type theory" that's not correct.
> >> Two entity of different signature must have
> >> different types. Otherwise a many to one
> >> relationship takes place.
> >>
> >> --
> >> 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
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals


Received on 2024-07-31 21:42:28