Date: Sun, 19 Jul 2020 16:43:40 +0000
> But we already have function overloading, which gives you the same thing with a much simpler syntax.
Your example code could be (in C++98 and later)
Ok, I should have clarified that point. The issue with this is the programmer has to copy / paste and then maintain two different functions. It just so happened with the example I was working with this is less convenient than having the different behavior internal to a single function rather than maintained externally via overloading and calling two different functions. Of course, overloading is a perfectly valid solution, just more work in this case. It often will not always be this way.
> Notice that in your specific case, `mode` has only two meaningful values — "1" and "not 1" — and so it should probably be a `bool`, not an `int`.
Ok, it's just the case for the limited small example I copied here, this isn't the complete function, the actual thing is a couple of hundred lines.
> Even better for your rapid-prototyping work:
int draw(int param);
int draw_with_mode(int param, int mode);
draw_with_mode(1, -1);
This is a good point, but consider the case of more than just a single optional argument. For M optional arguments, the number of function calls goes like 2^M... probably... I haven't given it much thought. Or is it factorial(M). Probably the latter.
Best Regards
________________________________
From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Sent: Sunday, July 19, 2020 16:34
To: Std-Proposals <std-proposals_at_[hidden]>
Cc: Ed Bird <HYPER-NOVA_at_[hidden]>
Subject: Re: [std-proposals] Proposal: template function solution to Pythonic optional function arguments
On Sun, Jul 19, 2020 at 11:45 AM Ed Bird via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> wrote:
Hi,
I am not sure if this is the correct email address to which I should direct this enquiry
It is (I mean I don't know a better place, except for /r/cpp or the Cpplang Slack or I think there's a Discord now).
[...] In my view, if a function has an optional argument, then it should be treated similarly to how template classes are treated. In other words, this is an example of a case where one block of code should produce multiple blocks of executable code when compiled.
But we already have function overloading, which gives you the same thing with a much simpler syntax.
Your example code could be (in C++98 and later)
void draw(int parameter) {
do_draw(parameter);
}
void draw(int parameter, int mode) {
do_draw(mode == 1 ? -1 : parameter);
}
We also have default function arguments, although I recommend against their use:
https://quuxplusone.github.io/blog/2020/04/18/default-function-arguments-are-the-devil/
void draw(int parameter, int mode = 42) {
do_draw(mode == 1 ? -1 : parameter);
}
Notice that in your specific case, `mode` has only two meaningful values — "1" and "not 1" — and so it should probably be a `bool`, not an `int`.
I don't personally like the syntax of using `#if` to achieve the anticipated result, but this is just my personal opinion
Indeed, you can't use preprocessor macros for this, because the C preprocessor doesn't know anything about functions or variables or anything like that. That's also why C++ templates use the dedicated `template` keyword, instead of some weird code-duplicating macro magic.
I actually introduced a bug due to the fact that I had a long list of default parameters, and missed one when calling the function. An implicit cast from int to bool was responsible for the function behaving differently to how I expected. I fixed this by putting in the missing arguments, of course.
Indeed. Default function arguments are the devil.
But it wouldn't have happened if I could have done `draw(1, mode=-1);`
Even better for your rapid-prototyping work:
int draw(int param);
int draw_with_mode(int param, int mode);
draw_with_mode(1, -1);
with no default function arguments at all. This way you can't accidentally forget the mode; if you try to call `draw_with_mode(1)` you get a compiler error.
Of course I can't stop you from spelling it `draw2` instead of `draw_with_mode`. ;)
HTH,
Arthur
Your example code could be (in C++98 and later)
Ok, I should have clarified that point. The issue with this is the programmer has to copy / paste and then maintain two different functions. It just so happened with the example I was working with this is less convenient than having the different behavior internal to a single function rather than maintained externally via overloading and calling two different functions. Of course, overloading is a perfectly valid solution, just more work in this case. It often will not always be this way.
> Notice that in your specific case, `mode` has only two meaningful values — "1" and "not 1" — and so it should probably be a `bool`, not an `int`.
Ok, it's just the case for the limited small example I copied here, this isn't the complete function, the actual thing is a couple of hundred lines.
> Even better for your rapid-prototyping work:
int draw(int param);
int draw_with_mode(int param, int mode);
draw_with_mode(1, -1);
This is a good point, but consider the case of more than just a single optional argument. For M optional arguments, the number of function calls goes like 2^M... probably... I haven't given it much thought. Or is it factorial(M). Probably the latter.
Best Regards
________________________________
From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Sent: Sunday, July 19, 2020 16:34
To: Std-Proposals <std-proposals_at_[hidden]>
Cc: Ed Bird <HYPER-NOVA_at_[hidden]>
Subject: Re: [std-proposals] Proposal: template function solution to Pythonic optional function arguments
On Sun, Jul 19, 2020 at 11:45 AM Ed Bird via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> wrote:
Hi,
I am not sure if this is the correct email address to which I should direct this enquiry
It is (I mean I don't know a better place, except for /r/cpp or the Cpplang Slack or I think there's a Discord now).
[...] In my view, if a function has an optional argument, then it should be treated similarly to how template classes are treated. In other words, this is an example of a case where one block of code should produce multiple blocks of executable code when compiled.
But we already have function overloading, which gives you the same thing with a much simpler syntax.
Your example code could be (in C++98 and later)
void draw(int parameter) {
do_draw(parameter);
}
void draw(int parameter, int mode) {
do_draw(mode == 1 ? -1 : parameter);
}
We also have default function arguments, although I recommend against their use:
https://quuxplusone.github.io/blog/2020/04/18/default-function-arguments-are-the-devil/
void draw(int parameter, int mode = 42) {
do_draw(mode == 1 ? -1 : parameter);
}
Notice that in your specific case, `mode` has only two meaningful values — "1" and "not 1" — and so it should probably be a `bool`, not an `int`.
I don't personally like the syntax of using `#if` to achieve the anticipated result, but this is just my personal opinion
Indeed, you can't use preprocessor macros for this, because the C preprocessor doesn't know anything about functions or variables or anything like that. That's also why C++ templates use the dedicated `template` keyword, instead of some weird code-duplicating macro magic.
I actually introduced a bug due to the fact that I had a long list of default parameters, and missed one when calling the function. An implicit cast from int to bool was responsible for the function behaving differently to how I expected. I fixed this by putting in the missing arguments, of course.
Indeed. Default function arguments are the devil.
But it wouldn't have happened if I could have done `draw(1, mode=-1);`
Even better for your rapid-prototyping work:
int draw(int param);
int draw_with_mode(int param, int mode);
draw_with_mode(1, -1);
with no default function arguments at all. This way you can't accidentally forget the mode; if you try to call `draw_with_mode(1)` you get a compiler error.
Of course I can't stop you from spelling it `draw2` instead of `draw_with_mode`. ;)
HTH,
Arthur
Received on 2020-07-19 11:47:00