Thread overview
Variadic Struct Parameter
Jan 12, 2021
Jonathan Levi
Jan 12, 2021
Q. Schroll
Jan 12, 2021
Jonathan Levi
Jan 12, 2021
Ali Çehreli
Jan 12, 2021
ryuukk_
Jan 12, 2021
Q. Schroll
January 12, 2021
Why is this not working?

```
struct S {
    int x;
    string y;
}

void fun(S s ...) {
    writeln(s);
}

void main() {
    fun(S(5,"hi"));
    fun(5,"hi");
}
```

Why does `fun` compile if calling it does not?
January 12, 2021
On Tuesday, 12 January 2021 at 17:26:15 UTC, Jonathan Levi wrote:
> Why is this not working?
>
> ```
> struct S {
>     int x;
>     string y;
> }
>
> void fun(S s ...) {

This is intended for arrays and classes, not structs. Using ... for something other than arrays and c

>     fun(S(5,"hi"));

That one should compile...

>     fun(5,"hi");

and the second one not.

It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.
January 12, 2021
On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
> It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.

I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering).

But why does this compile?

```
struct S {/*...*/}

void fun(S s...) {/*...*/}
```
If structs do not work as variadic parameters, why does `fun` still compile?
January 12, 2021
On 1/12/21 10:44 AM, Jonathan Levi wrote:

> why does `fun` still compile?

I'm not familiar with that particular syntax, I don't know why it compiles, and I don't know why structs are different. :) However, it looks very much like the following *slice* syntax:

void fun(S[] s...) {
    writeln(s);
}

In that case, the function receives a slice (to an array on the stack; so, do not keep a reference to it). Is that what you want?

Ali

January 12, 2021
On Tuesday, 12 January 2021 at 18:44:53 UTC, Jonathan Levi wrote:
> On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
>> It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.
>
> I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering).
>
> But why does this compile?
>
> ```
> struct S {/*...*/}
>
> void fun(S s...) {/*...*/}
> ```
> If structs do not work as variadic parameters, why does `fun` still compile?


you can do this:

```
import std.stdio;
import core.internal.moving;
import core.memory;

void main()
{
    auto a = Data(1);
    auto b = Data(2);
    auto c = Data(3);

    hello(a, b, c);
}

void hello(Data...)(Data args)
{
    writeln("n: ", args.length);
    foreach (data; args)
        writeln(data);
}

struct Data
{
    int a = 5;
}
```

this works fine: https://run.dlang.io/is/YA9syo
January 12, 2021
On 1/12/21 2:49 PM, ryuukk_ wrote:
> On Tuesday, 12 January 2021 at 18:44:53 UTC, Jonathan Levi wrote:
>> On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
>>> It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.
>>
>> I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering).
>>
>> But why does this compile?
>>
>> ```
>> struct S {/*...*/}
>>
>> void fun(S s...) {/*...*/}
>> ```
>> If structs do not work as variadic parameters, why does `fun` still compile?
> 
> 
> you can do this:
> 
> ```
> import std.stdio;
> import core.internal.moving;
> import core.memory;
> 
> void main()
> {
>      auto a = Data(1);
>      auto b = Data(2);
>      auto c = Data(3);
> 
>      hello(a, b, c);
> }
> 
> void hello(Data...)(Data args)

this is a template parameter named 'Data' that supersedes the module-level type named 'Data'. Not the same thing.

-Steve
January 12, 2021
On Tuesday, 12 January 2021 at 18:44:53 UTC, Jonathan Levi wrote:
> On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
>> It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.
>
> I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering).
>
> But why does this compile?
>
> ```
> struct S {/*...*/}
>
> void fun(S s...) {/*...*/}
> ```
> If structs do not work as variadic parameters, why does `fun` still compile?

Because D does allow you to specify things that have no effect. People sometimes complain about this as nonsense, but it has its merits in meta-programming:

void fun(T)(T t...) { }

Here, if T is a class or array type (including static arrays, btw), the dots have an effect, otherwise not. It would be unnecessary to require a split on the basis what T is.
January 12, 2021
On 1/12/21 12:46 PM, Q. Schroll wrote:
> On Tuesday, 12 January 2021 at 17:26:15 UTC, Jonathan Levi wrote:
>> Why is this not working?
>>
>> ```
>> struct S {
>>     int x;
>>     string y;
>> }
>>
>> void fun(S s ...) {
> 
> This is intended for arrays and classes, not structs. Using ... for something other than arrays and c
> 
>>     fun(S(5,"hi"));
> 
> That one should compile...
> 
>>     fun(5,"hi");
> 
> and the second one not.
> 
> It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.

Originally, structs did not allow a constructor. I'm thinking probably when they got constructors, the (almost never-used) variadic form of class parameter passing did not get ported to structs.

-Steve