C++ Logo

std-proposals

Advanced search

Re: Flexible function parameters

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 9 Jul 2020 12:51:02 -0400
On Thu, Jul 9, 2020 at 11:07 AM Filippo Casarin via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> I haven't explained what it does in the first mail so i will explain now.
> This proposal introduces more ways to overload a function.
>
> What is `void f(int x, int y) {}` supposed to do differently from `void
>> f(int x; int y) {}` or `void f(int x: int y) {}`?
>
> In this case for the machine there is no difference other than the name
> mangling.
>

So they're mangled differently? Does that mean that
int f(int x; int y);
int f(int x, int y);
forms a valid overload set?

Given
int g(int x; int y);
auto pg = &g;
what is the type of `pg`? Is it `int (*)(int;int)`? Is that type
convertible to `int (*)(int,int)` — why or why not?


Given the code
>
>> void foo(int a=1000696967, int b=1000696969);
>>
> In c++20 there is no way to call `foo` specifying a value for `b` but not
> for `a`
>
> With this proposal you will be allowed to do it in the following way
>
>> void foo(int a=1000696967; int b=1000696969);
>> foo(; 7); // calling foo with default valute for `a` and `b` = 7
>>
>
That doesn't follow from your original proposal at all!
Vice versa, we could discard everything from your original proposal and
simply propose *instead* that
    int h(int x=1, int y=2);
    ... h(,42) ...
should call `h(1,42)`.
This has already been proposed and rejected, AFAIK (maybe someone else can
dig up the proposal).
Vice versa, it has certainly been cited as a *reason* to reject
Python-style trailing commas: Python permits
    int f(int x, int y);
    ... f(1,2,) ...
with the same meaning as
    ... f(1,2) ...
https://godbolt.org/z/4Whnax
and this would be very nice to have in C++ as well — but people have said
"We should hold off on that, because maybe trailing-comma should mean
'argument omitted,' " exactly as you are now proposing.

Besides, consider that we could get *that* feature in several different
ways. The obvious one would be
    int h(int x=1, int y=2);
    ... h(default, 42) ...
This might be considered better anyway (certainly I consider it better)
because it reduces the possibility of the classic DO10I typo
<https://courses.cs.washington.edu/courses/cse505/94au/imperative/fortran.html>
:
    h(,42); // calls h(1, 42)
    h(.42); // calls h(0, 2)

Many of my complaints here are informed by the inference that you're trying
to find new and crazier ways to shoehorn default function arguments into
the language, when default function arguments are already a huge source of
confusion and bugs in real code:
https://quuxplusone.github.io/blog/2020/04/18/default-function-arguments-are-the-devil/


In c++20 you can't have multiple parameters packs in a function, the only
> solution I know is from the std::pair constructor but it's too long to call
>
>> std::pair<std::complex<double>, std::string> p6( // from
>> https://en.cppreference.com/w/cpp/utility/pair/pair
>> std::piecewise_construct,
>> std::forward_as_tuple(0.123, 7.7),
>> std::forward_as_tuple(10, 'a'));
>>
>
> The new syntax would be
>
>> std::pair<std::complex<double>, std::string> p6(0.123, 7.7; 10, 'a');
>>
>
Interesting. So you would make `...` parameter packs work *only* with
comma-separated arguments?
    template<class... Ts> void p(Ts... ts) {}
    p(1,2,3); // OK
    p(1;2;3); // invalid
    p(1:2:3); // invalid
Would you provide a way to use packs with : and ; arguments? Why or why not?
Consider
    void q(auto... ts; int i=1) {}
    q(42); // does this call q(42;1) or q(;42)? why?
    void r(auto... ts; auto... us) {}
    r(42); // does this call r(42;) or r(;42) or is it ambiguous or is it
invalid? why?


The colon has been included just for the slice because other possibilities
> didn't look as good
>>
>> arr[i:j] // slicing an array
>>
> arr[i, j] // indexing a matrix
>>
> arr[i; j] // does not mean anything to me
>>
>
Here's a possibility that looks even better:
    arr.slice(i, j) // slicing an array (C++98)
    m.at(i, j) // indexing a matrix (C++98)
    m[i, j] // indexing a matrix (C++23)

–Arthur

Received on 2020-07-09 11:54:30