Issue 10491 - Type inference for function arguments with default value
Summary: Type inference for function arguments with default value
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords: pull
: 17186 (view as issue list)
Depends on:
Blocks:
 
Reported: 2013-06-27 18:05 UTC by bearophile_hugs
Modified: 2023-05-18 10:51 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2013-06-27 18:05:52 UTC
Sometimes I have code like this:

struct VeryLongNamedStruct {}
void foo(in VeryLongNamedStruct x = VeryLongNamedStruct(1)) {}
void main() {}

Or even:

void bar(in TupleFoo x = TupleFoo(TupleBar(2), TupleSpam(3))) {}

In those cases something I'd like to use "auto" in the function signature for the arguments that have a default value:

void foo(in auto x = VeryLongNamedStruct(1)) {}

A bit more complex case:

void spam(T)(const x = Foo!T(4)) {}

This is not an important new enhancement request (not all enhancement requests have the same importance level), it doesn't allow to do new things, and its priority is low, but (assuming it's not too much work to implement) I think it's a handy small feature. It acts similarly to normal variable definitions, so I think there is nothing much new to learn for D programmers.
Comment 2 Kenji Hara 2013-06-28 21:13:50 UTC
I don't like the enhancements of this kind. Because:

1. Default argument is not so often used. Then, reduction amount of the code is very limited.
2. It breaks consistency of C-style languages that all of function parameters in function signature have their own type explicitly.
3. It would introduce one more forward reference possibility.

void foo(auto a = bar()) {}   // inference

auto bar()
{
    alias T = ParameterTypeTuple!foo[0];   // requires foo's complete signature
    return T.init;
}

void main()
{
    auto x = bar();
}

Already, auto return, function attribute inference has same possibility. They sometimes produces legitimate (but difficult to understand) forward reference errors.

4. `auto ref` / `in ref` is still debatable. This enhancement might have interference with it. 

----

Side note: Today, issue 7152 is implemented. By that,

void foo(in VeryLongNamedStruct x = VeryLongNamedStruct(1)) {}

might be shorten to:

void foo(in VeryLongNamedStruct x = 1) {}
Comment 3 bearophile_hugs 2013-06-29 01:24:25 UTC
(In reply to comment #2)

Thank you for the comments Kenji.

> 1. Default argument is not so often used. Then, reduction amount of the code is
> very limited.

I agree. This is why I said it's not an important enhancement request. It's handy, but not often.


> 2. It breaks consistency of C-style languages that all of function parameters
> in function signature have their own type explicitly.

I think this is not much relevant. It doesn't break valid C code.


> 3. It would introduce one more forward reference possibility.
> 
> void foo(auto a = bar()) {}   // inference
> 
> auto bar()
> {
>     alias T = ParameterTypeTuple!foo[0];   // requires foo's complete signature
>     return T.init;
> }
> 
> void main()
> {
>     auto x = bar();
> }
> 
> Already, auto return, function attribute inference has same possibility. They
> sometimes produces legitimate (but difficult to understand) forward reference
> errors.

Right, the more type inference you add, the more complex is for the compiler (and sometimes for the programmer too) to understand the code and make it work. Using ParameterTypeTuple on an inferenced argument type looks like a way to stress the type inferencer.


> 4. `auto ref` / `in ref` is still debatable. This enhancement might have
> interference with it.

"in ref" is not a problem, because this is not valid code:

struct Foo { int x; }
int foo(in ref Foo f = Foo(1)) {}

So this is not valid code:

struct Foo { int x; }
int foo(in ref f = Foo(1)) {}


This is currently valid:

struct Foo { int x; }
int foo()(auto ref Foo f = Foo(1)) {}

So this should be valid:

struct Foo { int x; }
int foo()(auto ref f = Foo(1)) {}



> Side note: Today, issue 7152 is implemented. By that,
> 
> void foo(in VeryLongNamedStruct x = VeryLongNamedStruct(1)) {}
> 
> might be shorten to:
> 
> void foo(in VeryLongNamedStruct x = 1) {}

Right. But my use case was a bit more complex, more like:

void foo(in VeryLongNamedStruct y = VeryLongNamedStruct(1, 2)) {}


I am grateful to Henning Pohl for writing the patch.
So do we close down this enhancement request?
Comment 4 bearophile_hugs 2013-06-30 17:07:20 UTC
(In reply to comment #1)
> https://github.com/D-Programming-Language/dmd/pull/2270

I think a decision should be taken. What do you think about this issue Henning Pohl?
Comment 5 bearophile_hugs 2013-07-02 00:29:40 UTC
OK, closed.
Comment 6 Henning Pohl 2013-07-02 13:04:46 UTC
(In reply to comment #4)
> (In reply to comment #1)
> > https://github.com/D-Programming-Language/dmd/pull/2270
> 
> I think a decision should be taken. What do you think about this issue Henning
> Pohl?

Can only three people actually take decisions like that?

Let me comment on Kenji's four points:

1. True, but these little syntactic improvements make writing D more fun as a whole.

2. This is what D should do more often.

3. The cost of inferring things. If the quality of the error messages are appropriate, it is totally worth it.

4. In which way do "in ref" and "auto ref" conflict with this?

Walter has underlined multiple times the importance of beautiful code. And that is the goal of this enhancement.
Comment 7 bearophile_hugs 2013-07-02 14:00:23 UTC
(In reply to comment #6)

> Can only three people actually take decisions like that?

I'd like Walter and/or Andrei to give a comment to this (and to your patch).

I have asked here, in the main D newsgroup, and your patch was exposed in GitHub for several days.


> 1. True, but these little syntactic improvements make writing D more fun as a
> whole.

Default arguments are not so common...



> 3. The cost of inferring things. If the quality of the error messages are
> appropriate, it is totally worth it.

The point 3 by Hara is probably the most important. If he says this enhancement may cause more typing problems then we should listen to him. At minimum your patch should contain more tests. (But adding tests to a patch is receiving a cold interest risks being a further waste of time.)

Thank you for your patch and your comments.
Comment 8 Walter Bright 2013-07-09 13:17:59 UTC
While I agree that this would be a nice enhancement, I'm with Kenji in worrying about ever more complex forward reference problems. I don't think it is worth the effort to overcome those problems at the moment, since as Kenji also pointed out, default arguments are not used often.
Comment 9 RazvanN 2023-05-18 10:51:17 UTC
*** Issue 17186 has been marked as a duplicate of this issue. ***