Jump to page: 1 2 3
Thread overview
Anonymous structs
Feb 11, 2013
Jacob Carlborg
Feb 11, 2013
Nick Sabalausky
Feb 12, 2013
Jacob Carlborg
Feb 12, 2013
Russel Winder
Feb 13, 2013
Martin Nowak
Feb 13, 2013
Jacob Carlborg
Feb 11, 2013
Era Scarecrow
Feb 12, 2013
Jacob Carlborg
Feb 12, 2013
Era Scarecrow
Feb 12, 2013
Jacob Carlborg
Feb 12, 2013
Era Scarecrow
Feb 13, 2013
Jacob Carlborg
Feb 13, 2013
Era Scarecrow
Feb 13, 2013
Jacob Carlborg
Feb 13, 2013
Era Scarecrow
Feb 13, 2013
Jacob Carlborg
Feb 11, 2013
MattCoder
Feb 12, 2013
Jacob Carlborg
Feb 11, 2013
Brian Schott
Feb 12, 2013
Jacob Carlborg
Feb 13, 2013
Michael
February 11, 2013
I've been thinking for this feature for a while. An anonymous struct is basically what it sound like, a struct without a name. The inserting part is its members. If two anonymous structs have the same members (not necessarily in the same order) they are considered to be of the same type. This shows how anonymous structs looks like:

{ int x, int y } point = { y: 4, x: 5 };
auto point2 = { x: 1, y: 2 };
point = point2;

In this example "point" and "point2" are of the same type since they have the same members. This is basically lowered to something similar to:

struct __AnonymousStruct_int_x_int_y
{
    int x;
    int y;
}

__AnonymousStruct_int_x_int_y point;
point.y = 4;
point.x = 5;

__AnonymousStruct_int_x_int_y point2;
point2.x = 1;
point2.y = 2;
point = point2;

The compiler will implicitly generate a new struct type with a name that will always be the same if it has the same members. These structs will then behave just like any other structs, accessing members and so on.

assert(point2.x == 1);
assert(point.y == 2);

The advantage of anonymous structs is that they can be declared in place, in function declartions for example:

void foo ({ int x, int y } point)
{
}

foo({ y: 5, x: 3 });

When calling a function and passing in an anonymous structs it's possible to drop the braces to get a more pleasing and less verbose syntax:

foo(y: 5, x: 3);

With this syntax sugar we can basically get named parameters. With the braces it also looks like JSON.

Anonymous structs can be implicitly converted to and from regular named struts:

* Named struct to anonymous struct:

struct Bar
{
    int x;
    int y;
}

foo(Bar(1, 2));

* Anonymous struct to named struct:

void bar (Bar b) {}

bar(x: 3, y: 4);

It would also be nice to have opDispatch soak up everything that doesn't match, if it's declared in a named struct:

struct Options
{
    int x;
    int y;
    private Variant[string] members;

    void opDispatch (string name, T) (T t)
    {
        members[name] = Variant(t);
    }
}

void fooBar (Options options) {}

fooBar(x: 5, a: "asd", y: 1.2, b: 4);

"x" and "y" are matched with the regular members, "a" and "b" are matched to opDispatch which takes care of them.

Perhaps this initializer syntax can be used for classes as well:

class FooBar
{
    int x;
    int y;
}

FooBar fb = { x: 3, y: 5 };

The above would be lowered to:

FooBar fb = new FooBar();
fb.x = 3;
fb.y = 5;

Thoughts?

-- 
/Jacob Carlborg
February 11, 2013
Isn't that all basically syntax sugar for tuples?
February 11, 2013
On Monday, 11 February 2013 at 21:30:52 UTC, Jacob Carlborg wrote:
> I've been thinking for this feature for a while. An anonymous struct is basically what it sound like, a struct without a name. The inserting part is its members. If two anonymous structs have the same members (not necessarily in the same order) they are considered to be of the same type. This shows how anonymous structs looks like:
>
> { int x, int y } point = { y: 4, x: 5 };
> auto point2 = { x: 1, y: 2 };
> point = point2;
>
> In this example "point" and "point2" are of the same type since they have the same members. This is basically lowered to something similar to:

 What if there's another anonymous struct that has a little more?

  { int x, int y } point = { y: 4, x: 5 };
  { int x, int y, int color } color_point
          = { y: 4, x: 5, color: 0x000000 };
  //which anonymous struct does it go with?
  //Or can auto only work with named/returned structs?
  auto point2 = { x: 1, y: 2 };

  point = point2; //error, point2 type void _error

 We can instantiate structs with fewer arguments than elements they hold. It would either have to go the safe route, or try it's best to either be 'safe' or 'whatever seems to work' until you change something and break it utterly with no description of 'what' it is.

 Anonymous structs would be more useful as single instances like unions can be in C. (I think it's disallowed in D, or I had trouble with them)

Nick Sabalausky wrote:
>Isn't that all basically syntax sugar for tuples?

 Maybe. I would think an explicit tuple would be better.
February 11, 2013
On Monday, 11 February 2013 at 21:30:52 UTC, Jacob Carlborg wrote:
> The advantage of anonymous structs is that they can be declared in place, in function declartions for example:
>
> void foo ({ int x, int y } point)
> {
> }
>
> foo({ y: 5, x: 3 });

At the first look it seems interesting, but imagine that you need to change one type or add more members to that struct, have you imagined the mess to change all those declarations?

Because that case I prefer the old way:

void foo(MyPointStruct point)
{
}

Any changing in "MyPointStruct" will be consumed by all the code.
February 11, 2013
On Monday, 11 February 2013 at 21:30:52 UTC, Jacob Carlborg wrote:
> { int x, int y } point = { y: 4, x: 5 };

That looks like it would confuse the parser because it looks almost exactly like a BlockStatement until you get several tokens in.
February 12, 2013
On 2013-02-11 22:54, Nick Sabalausky wrote:
> Isn't that all basically syntax sugar for tuples?

I didn't really thing of tuples, but it might be considered that. I assume you are referring to std.typecons.Tuple? Except the syntax, there are some limitations with Tuple. It cannot be implicitly converted to other types based on its members. I don't know if that's possible to fix. It can also contain just types, or just values.

BTW, isn't tuples and structs basically the same thing in the end.

-- 
/Jacob Carlborg
February 12, 2013
On 2013-02-11 23:20, Era Scarecrow wrote:

>   What if there's another anonymous struct that has a little more?
>
>    { int x, int y } point = { y: 4, x: 5 };
>    { int x, int y, int color } color_point
>            = { y: 4, x: 5, color: 0x000000 };
>    //which anonymous struct does it go with?
>    //Or can auto only work with named/returned structs?
>    auto point2 = { x: 1, y: 2 };
>
>    point = point2; //error, point2 type void _error

"point2" is completely independent of the other declarations. But you can think of it having the same type as "point". It can also be implicitly converted to "color_point". It's not the actual type that's interesting, it's the members. The compiler checks the members to see if two values are of the same types.

>   We can instantiate structs with fewer arguments than elements they
> hold. It would either have to go the safe route, or try it's best to
> either be 'safe' or 'whatever seems to work' until you change something
> and break it utterly with no description of 'what' it is.

It's not the actual type that's interesting, as long as the members match they're considered to be the same type.

-- 
/Jacob Carlborg
February 12, 2013
On 2013-02-11 23:58, MattCoder wrote:
> On Monday, 11 February 2013 at 21:30:52 UTC, Jacob Carlborg wrote:
>> The advantage of anonymous structs is that they can be declared in
>> place, in function declartions for example:
>>
>> void foo ({ int x, int y } point)
>> {
>> }
>>
>> foo({ y: 5, x: 3 });
>
> At the first look it seems interesting, but imagine that you need to
> change one type or add more members to that struct, have you imagined
> the mess to change all those declarations?

If you add a new member to the anonymous struct declared in "foo" any existing call will still match. That's just like the current initializer syntax works:

struct Bar
{
    int a;
    int b;
}

Bar bar = { b: }; // "a" is default initialized

If you remove a member from the anonymous struct declared in "foo" you will get a compile error since there will be a member that doesn't match.

> Because that case I prefer the old way:
>
> void foo(MyPointStruct point)
> {
> }
>
> Any changing in "MyPointStruct" will be consumed by all the code.

I'm not sure I see the difference compared with the anonymous struct.

-- 
/Jacob Carlborg
February 12, 2013
On 2013-02-12 00:17, Brian Schott wrote:

> That looks like it would confuse the parser because it looks almost
> exactly like a BlockStatement until you get several tokens in.

That might be the case, I have no idea. Is there another syntax that would work better that could fit in a function declaration as well?

-- 
/Jacob Carlborg
February 12, 2013
On Mon, 2013-02-11 at 16:54 -0500, Nick Sabalausky wrote:
> Isn't that all basically syntax sugar for tuples?

At EuroPython 2010 Guido van Rossum reported that tuple literals were always intended to be thought of as struct literals.

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


« First   ‹ Prev
1 2 3