I don't quite understand how the proposal is different from something like tag-invoke using templates, or regular function overloading. It'd convert the expression into a tag to use for invoking. Similarly, we can use template arguments to "assure" that something was checked before:
float sqrt(float v assure(v>=0)) {
if (v<0) throw std::runtime_error(...);
...
}
is basically the same as
template <bool isKnownPositive>
float sqrt(float v) {
if (v<0) throw std::runtime_error(...);
return sqrt<true>(v);
}
template <>
float sqrt<true>(float v) {
...
}
which doesn't seem like much of an improvement? It has the same code bloat that templates has - arguably more, in case you have multiple assurements that not all are used - and it's a language addition that usually comes with a very high bar of "this is impossible to do right now without this".
Why should we change the language for this instead of teaching the users about tag invoke?
And in many cases it's changing a narrow contract (f only works on nonnegative numbers) into a wide contract (f works on anything but throws on negative), with an optimization to go back to the narrow contract. It's likely better to use the narrow contract in all cases instead.
Best regards,
Peter
Right.
Actually I realized [[assume]] is almost the same, so assure may be superfluous.
If I understand your proposal correcly, helped by clarifications asked by many, it is the following:
- A function marked with one or more `assure(x)` is compiled in multiple different variants, one for each combination of assures.
- Calling such a function can be marked by one or more such `assure(x)` expressions, which calls the variant that matches the assurances it gives.
With the idea that if your caller guarantees it's not negative, you can use the fast code path, and if they cannot it's the slow path. Similarly, you could imagine a sqrt(complex) that has a faster implementation if it's only a real argument, with a similar
assure(
c.im == 0) added.
Basically, overloading on runtime argument guarantees.
Is that correct?
Yeah, you're right. We should think of a way to find entry point, such as processing assure before compiling codes so that compiler can generate entry points.
If the function is not inlined? The optimization will be invaild. Optimizing without inline is the main work of assure.
No. Caller just finds the case it need.
How is the caller supposed to know if it does not see the function definition? I would claim this is the common case. Mostly inline functions are visible to the caller and the optimizer does already the right thing as mentioned before.
The function declaration would need a way to specify which assures are valid.
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--