December 16, 2012
On Sunday, 16 December 2012 at 06:38:13 UTC, anonymous wrote:
> On Saturday, 15 December 2012 at 16:32:27 UTC, r_m_r wrote:
>> On 12/15/2012 08:57 PM, anonymous wrote:
>>> Note that here s1alpha and s2alpha are distinct types.
>>
>> what about this: http://dpaste.dzfl.pl/95f7a74d
>
> Consider
>
> struct Foo {mixin (genStruct!("s1"));}
> struct Bar {mixin (genStruct!("s1"));}
>
> Foo.s1alpha and Bar.s1alpha are the same type. In my version they are not.


Yes, they should be the same type. If you are inserting an actual struct with the same name("s1") then you would expect them to be identical. (else you could just do something like mixin(genStruct!("_1", "s1")); to get a different copy of the struct.

But we are not talking about inserting a field but "combining" structs.

I think the updated answer is more pertinent:

http://dpaste.dzfl.pl/d9f001db

Here we are "inserting" a struct(well, now it is simply a template) into another(not a struct field, different things).

struct B { int x; }
struct A { Insert(B); }

should be indentical to

struct A { int x; }

r_rm_r has parameterized it so that it's really A!(B) which is better so we can combine them in many ways.

What all this is analogous to is multiple inheritance at compile time. A inherits B, so to speak. It is helpful in breaking down larges structs into smaller ones and being able to mix and match.

One could also think of it as an algebra of structs.

It would be nice to be able to do stuff like

A + B, A - B(possibly useless), A*B(possibly useless), etc...

A + B would just combine the members, A - B could remove the members that overlap, A*B could qualify overlapping members.

struct A
{
  int x;
  int y;
}

struct B
{
  int x;
  int z;
}

A + B <==>

struct ApB {
  int x;   // Possible error because of overlap
  int y;
  int z;
}

A - B <==>
struct AmB {
   int y;
   int z;
}

A*B <==>
struct AtB {
   int x.A;
   int x.B;
   int y;
   int z;
}

or whatever. The usefulness is mainly that you can decompose a struct into pieces then recombine them into something possibly different. I'm not interested in the algebra aspect, just the ability to break down into two pieces, one I supply, one the user of the struct supplies. A simple A + B type of operation. The point, is, a lot of possible with such a feature. Possibly no one will use it but it could be quite powerful if it was designed appropriately.




December 16, 2012
On Sunday, 16 December 2012 at 08:49:10 UTC, js.mdnq wrote:
> On Sunday, 16 December 2012 at 06:38:13 UTC, anonymous wrote:
>> On Saturday, 15 December 2012 at 16:32:27 UTC, r_m_r wrote:
>>> On 12/15/2012 08:57 PM, anonymous wrote:
>>>> Note that here s1alpha and s2alpha are distinct types.
>>>
>>> what about this: http://dpaste.dzfl.pl/95f7a74d
>>
>> Consider
>>
>> struct Foo {mixin (genStruct!("s1"));}
>> struct Bar {mixin (genStruct!("s1"));}
>>
>> Foo.s1alpha and Bar.s1alpha are the same type. In my version they are not.
>
>
> Yes, they should be the same type. If you are inserting an actual struct with the same name("s1") then you would expect them to be identical.

I would not, actually. I'd expect it to behave like this:

struct Foo {struct s1 {}}
struct Bar {struct s1 {}}

and not like this:

struct s1 {}
struct Foo {alias .s1 s1;}
struct Bar {alias .s1 s1;}

However, if the alias version makes more sense in your case, by all means, use that one.
December 16, 2012
> it would be real nice if I there was a compile time construct for this. like "me" or something that would return type info inside the current
scope.

>
> class A(T) { this() { writeln(me.typeinfo.name); }
>
> would print "A(T)".
>
> (of course me is probably a bad name but just an example :)
>


You could use `typeof(this)`. It returns the static type of `this`.


December 16, 2012
> One could also think of it as an algebra of structs.
>
> It would be nice to be able to do stuff like
>
> A + B, A - B(possibly useless), A*B(possibly useless), etc...
>
> A + B would just combine the members, A - B could remove the members that overlap, A*B could qualify overlapping members.
>

Usually, given types A and B, A+B means `A or B` (in D,
std.typecons.Algebraic!(A,B) ) and A*B means the tuple containing A and B
(in D, std.typecons.Tuple!(A,B) ).


What you're trying to do is doable in D, but you'd have to define it a bit more:

if we have

struct A { int a; int b}
struct B { int b; int a} // just a and b swapped.

What is `A+B`? `A-B`?


December 16, 2012
On 12/16/2012 02:03 PM, js.mdnq wrote:
> That looks like it might be pretty close. I was also thinking that one
> could just use mixin templates of trying to do it with structs directly.

i dunno if this is what u want, but have a look: http://dpaste.dzfl.pl/f5616d77

cheers,
r_m_r
December 16, 2012
On Sunday, 16 December 2012 at 15:34:34 UTC, Philippe Sigaud wrote:
>> One could also think of it as an algebra of structs.
>>
>> It would be nice to be able to do stuff like
>>
>> A + B, A - B(possibly useless), A*B(possibly useless), etc...
>>
>> A + B would just combine the members, A - B could remove the members that
>> overlap, A*B could qualify overlapping members.
>>
>
> Usually, given types A and B, A+B means `A or B` (in D,
> std.typecons.Algebraic!(A,B) ) and A*B means the tuple containing A and B
> (in D, std.typecons.Tuple!(A,B) ).
>
>
> What you're trying to do is doable in D, but you'd have to define it a bit
> more:
>
> if we have
>
> struct A { int a; int b}
> struct B { int b; int a} // just a and b swapped.
>
> What is `A+B`? `A-B`?



(Thanks for the typeof(this) works great!)


Yes, A+B = A or B. Or is inclusive though.. and "overlap" and order is immaterial.

So `A+B` is equivalent to

struct ApB { int a; int b; }

Since order ultimately matters(the layout of the struct in memory) we could define

`B+A` =
struct BpA { int b; int a; }

`A-B` = `B-A` = (only in this case)
struct AmB { } = struct BmA { }


So A*B = std.typecons.Algebraic!(A,B) which is what I initially said * should be. That should take care of that operation. How do you do the other ops?



December 16, 2012
On Sunday, 16 December 2012 at 20:29:19 UTC, r_m_r wrote:
> On 12/16/2012 02:03 PM, js.mdnq wrote:
>> That looks like it might be pretty close. I was also thinking that one
>> could just use mixin templates of trying to do it with structs directly.
>
> i dunno if this is what u want, but have a look: http://dpaste.dzfl.pl/f5616d77
>
> cheers,
> r_m_r

Well, it a slightly another way and close. Let me see if I can come up with something that expresses better what I'm after. It will be a week or two though till I get around to it probably.
December 17, 2012
On 12/17/2012 04:33 AM, js.mdnq wrote:
> Well, it a slightly another way and close. Let me see if I can come up
> with something that expresses better what I'm after. It will be a week
> or two though till I get around to it probably.

OK. I'll just leave this here for future reference:
http://dpaste.dzfl.pl/d8faa96a
http://dpaste.dzfl.pl/fc88273b

regards,
r_m_r
December 17, 2012
On Monday, 17 December 2012 at 22:24:58 UTC, r_m_r wrote:
> On 12/17/2012 04:33 AM, js.mdnq wrote:
>> Well, it a slightly another way and close. Let me see if I can come up
>> with something that expresses better what I'm after. It will be a week
>> or two though till I get around to it probably.
>
> OK. I'll just leave this here for future reference:
> http://dpaste.dzfl.pl/d8faa96a
> http://dpaste.dzfl.pl/fc88273b
>
> regards,
> r_m_r

Cool. You have some useful stuff there. I'll have to go through it and see if it does what I want or could be used to do it. It looks like it does the combining so that is a definite plus. I think, though, one problem is, is you would want to wrap the user struct in a template because you might want to access the master's members from the user struct.

It looks like the approach 2 does what I'm looking for pretty nicely except that, If I'm not mistaken the user struct will error out when trying to access members from the master.


e.g.,

struct S_AB(AT, BT)
{
	AT A;
	BT B;
}

struct S_CD(CT, DT)
{
        void check() { writeln(A); } // error, No A
	CT C;
	DT D;
}

mixin ( gen!("S_ABCD", S_AB!(int, float), S_CD!(double, string)) );


I'm not actually sure about the best approach here. Using a template mixin will work but I like the look & feel of just using normal structs(as we don't have to access A in S_CD if we don't need too).

In any case, it seems your method does not work with methods? if I add the `check()` to your approach-2 it fails with several strange errors. Any ideas?

December 17, 2012
On 12/18/2012 04:42 AM, js.mdnq wrote:
> In any case, it seems your method does not work with methods? if I add
> the `check()` to your approach-2 it fails with several strange errors.
> Any ideas?
>

approach-2 can only combine struct fields (i.e., no method support - for that you have to use approach1).

regards,
r_m_r