Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 18, 2015 It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 Re: It's a class! It's a struct! It's ... SuperStruct! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 :)
|
Copyright © 1999-2021 by the D Language Foundation