Jump to page: 1 2
Thread overview
It's a class! It's a struct! It's ... SuperStruct!
Oct 18, 2015
rcorre
Oct 18, 2015
Meta
Oct 18, 2015
rcorre
Oct 18, 2015
rcorre
Oct 20, 2015
rcorre
Oct 18, 2015
Meta
Oct 19, 2015
Sönke Ludwig
Oct 19, 2015
Walter Bright
Oct 20, 2015
Vladimir Panteleev
Oct 21, 2015
burjui
Oct 22, 2015
Walter Bright
Oct 21, 2015
Timon Gehr
Oct 22, 2015
rcorre
Oct 23, 2015
rcorre
October 18, 2015
SuperStruct is a struct that acts like a class:

---
struct Square {
  float size;
  float area() { return size * size; }
}

struct Circle {
  float r;
  float area() { return r * r * PI; }
}

alias Shape = SuperStruct!(Square, Circle);

// look! polymorphism!
Shape sqr = Square(2);
Shape cir = Circle(4);
Shape[] shapes = [ sqr, cir ];

// call functions that are shared between the source types!
assert(shapes.map!(x => x.area).sum.approxEqual(2 * 2 + 4 * 4 * PI));
---

SuperStruct is basically a Variant that exposes the common members of its source
types. You can check it out here:

https://github.com/rcorre/superstruct

I'm not quite sure if this is a good idea (or if it already exists in some
form that I haven't seen), but it was fun to work on. There's a lot more info on
the README if you're curious. Let me know what you think!



If you're wondering why I even wanted to do something like this:

I had this Variant that stored either a SpriteBatch, a TextBatch, or a Primitive
batch. The thing is, I had a group of them that had to be sorted by depth. Each
one of those types _had_ a depth, but it just wasn't accessible through the
variant. Not a big deal, of course:

---
struct Batch {
  Algebraic!(SpriteBatch, TextBatch, PrimitiveBatch) _batch;
  auto depth() {
    return _batch.visit!(
        (SpriteBatch    b) => b.depth,
        (TextBatch      b) => b.depth,
        (PrimitiveBatch b) => b.depth);
  }
}
---

And that worked fine for a bit. Then each of them got a blender too:

---
  auto blender() {
    return _batch.visit!(
        (SpriteBatch    b) => b.blender,
        (TextBatch      b) => b.blender,
        (PrimitiveBatch b) => b.blender);
  }
---

Later, I thought it might be nice if a batch had a global transform.
You can probably guess what that looked like...

I started to think maybe Batch should be a class ... but these were value types,
dammit! All I wanted was a little polymorphism! Sure, theres std.typecons.wrap,
but that doesn't (yet) work on structs, and besides, it's really a class on the
inside!

Instead of (logically?) just using classes, I decided to go nuts with templates,
and so SuperStruct was born.

October 18, 2015
On Sunday, 18 October 2015 at 19:00:16 UTC, rcorre wrote:
You might find this interesting. It's an "outside-in" approach to the same problem as opposed to your "inside-out" approach. Not finished, but the general idea is there.

https://github.com/MetaLang/phobos/commit/c8132f53b791ed4a134dd456c8fd20d0d201731d
October 18, 2015
On Sunday, 18 October 2015 at 21:00:32 UTC, Meta wrote:
> On Sunday, 18 October 2015 at 19:00:16 UTC, rcorre wrote:
> You might find this interesting. It's an "outside-in" approach to the same problem as opposed to your "inside-out" approach. Not finished, but the general idea is there.
>
> https://github.com/MetaLang/phobos/commit/c8132f53b791ed4a134dd456c8fd20d0d201731d

That's just the kind of thing I was looking for! I actually started with a 'visitor' function that works similar to project:

https://github.com/rcorre/superstruct/blob/master/src/superstruct.d#L153-L166

then decided to wrap the whole thing in a struct to expose the members more 'naturally'.

I think having something like project in phobos would be pretty useful though.
October 18, 2015
On Sunday, 18 October 2015 at 21:18:52 UTC, rcorre wrote:
> On Sunday, 18 October 2015 at 21:00:32 UTC, Meta wrote:
>> On Sunday, 18 October 2015 at 19:00:16 UTC, rcorre wrote:
>> You might find this interesting. It's an "outside-in" approach to the same problem as opposed to your "inside-out" approach. Not finished, but the general idea is there.
>>
>> https://github.com/MetaLang/phobos/commit/c8132f53b791ed4a134dd456c8fd20d0d201731d
>
> That's just the kind of thing I was looking for! I actually started with a 'visitor' function that works similar to project:
>
> https://github.com/rcorre/superstruct/blob/master/src/superstruct.d#L153-L166
>
> then decided to wrap the whole thing in a struct to expose the members more 'naturally'.
>
> I think having something like project in phobos would be pretty useful though.

And at the risk of going a little overboard, I think the answer to supporting arbitrary templated functions is to wrap visitor/project itself in a template, that then returns a variadic function while passing along other compile-time args. Maybe. I haven't thought it through too carefully...




October 18, 2015
On Sunday, 18 October 2015 at 21:18:52 UTC, rcorre wrote:
> That's just the kind of thing I was looking for! I actually started with a 'visitor' function that works similar to project:
>
> https://github.com/rcorre/superstruct/blob/master/src/superstruct.d#L153-L166
>
> then decided to wrap the whole thing in a struct to expose the members more 'naturally'.
>
> I think having something like project in phobos would be pretty useful though.

Yeah, I'm planning on making a PR once I add in support for functions et al.
October 19, 2015
The TaggedAlgebraic type that I made some time ago is also related. It's roughly a superset in that it exposes all members of all types instead of only the common types:

https://github.com/s-ludwig/taggedalgebraic
October 19, 2015
On 10/18/2015 12:00 PM, rcorre wrote:
> SuperStruct is a struct that acts like a class:

I suggest it be renamed to 'shimmer':

http://www.nbc.com/saturday-night-live/video/shimmer-floor-wax/n8625

October 20, 2015
On 10/18/15 3:00 PM, rcorre wrote:
> SuperStruct is a struct that acts like a class:
[snip]

Nice. I discussed "Classify" a while back with this semantics. -- Andrei
October 20, 2015
On Sunday, 18 October 2015 at 21:26:55 UTC, rcorre wrote:
>
> And at the risk of going a little overboard, I think the answer to supporting arbitrary templated functions is to wrap visitor/project itself in a template, that then returns a variadic function while passing along other compile-time args. Maybe. I haven't thought it through too carefully...

Proof of concept for passing through compile-time args:

https://github.com/rcorre/superstruct/commit/27b99fae5eb1242ffcde31a7546771f35f8221f1

If at first you don't succeed, wrap everything in a template!
October 20, 2015
On Monday, 19 October 2015 at 10:27:26 UTC, Walter Bright wrote:
> On 10/18/2015 12:00 PM, rcorre wrote:
>> SuperStruct is a struct that acts like a class:
>
> I suggest it be renamed to 'shimmer':
>
> http://www.nbc.com/saturday-night-live/video/shimmer-floor-wax/n8625

"This video is not available from your location".

I haven't been able to find a mirror that's watchable from here either.

Might explain why no one in Brașov laughed at your joke :)
« First   ‹ Prev
1 2