Re: Runtime heterogeneous collections?

2019-01-19 Thread Steven O via Digitalmars-d-learn
I'd like to thank everyone for their help! I was finally able to 
do what I'd like. I didn't end up using a variant, but maybe 
there's a better way to do what I want using it, and I just 
couldn't figure it out.


Here's the solution I finally came up with:
https://run.dlang.io/is/GdDDBp

If anyone has any better solutions I'm all ears!


Re: Runtime heterogeneous collections?

2019-01-18 Thread Kagamin via Digitalmars-d-learn

On Thursday, 17 January 2019 at 02:21:21 UTC, Steven O wrote:

void main()
{
alias Rec_type = Tuple!(int, "x", int, "y", int, "z");
RedBlackTree!Rec_type[1] test;
}


alias Rec_type1 = Tuple!(int, "x", int, "y", int, "z");
alias Rec_type2 = Tuple!(int, "x", int, "y", string, "z");
Tuple!(RedBlackTree!Rec_type1, "x", RedBlackTree!Rec_type2, "z") 
test;


Similar questions were asked before, usually such heterogeneous 
collections are not the best solution to the problem at hand.


Re: Runtime heterogeneous collections?

2019-01-18 Thread Alex via Digitalmars-d-learn
On Friday, 18 January 2019 at 15:07:41 UTC, Steven Schveighoffer 
wrote:

On 1/18/19 9:58 AM, Alex wrote:
On Friday, 18 January 2019 at 13:31:28 UTC, Steven 
Schveighoffer wrote:

[...]


In this case, I would say Phobos lacks an appropriate 
interface definition, what do you think?


But what is the common interface between those 2 types? Even in 
Dcollections, where RedBlackTree came from, there was no 
interfaces that didn't specify the type they were dealing with. 
In other words, there is no common interface for sets of 2 
different types.


-Steve


Aha... I see... all important methods are templated on the 
element type... hmm.


Re: Runtime heterogeneous collections?

2019-01-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/18/19 10:10 AM, Neia Neutuladh wrote:

On Fri, 18 Jan 2019 10:07:41 -0500, Steven Schveighoffer wrote:

But what is the common interface between those 2 types? Even in
Dcollections, where RedBlackTree came from, there was no interfaces that
didn't specify the type they were dealing with. In other words, there is
no common interface for sets of 2 different types.


..empty(), .clear(), .length(), and .toString(sink, formatspec). Which is
kind of anemic. Might as well use Object.



Yeah, I didn't bother with any of those as base interfaces. Probably the 
most basic interface for dcollections was Iterator(V):


https://github.com/schveiguy/dcollections/blob/master/dcollections/model/Iterator.d#L40-L58

-Steve


Re: Runtime heterogeneous collections?

2019-01-18 Thread Neia Neutuladh via Digitalmars-d-learn
On Fri, 18 Jan 2019 10:07:41 -0500, Steven Schveighoffer wrote:
> But what is the common interface between those 2 types? Even in
> Dcollections, where RedBlackTree came from, there was no interfaces that
> didn't specify the type they were dealing with. In other words, there is
> no common interface for sets of 2 different types.

.empty(), .clear(), .length(), and .toString(sink, formatspec). Which is 
kind of anemic. Might as well use Object.


Re: Runtime heterogeneous collections?

2019-01-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/18/19 9:58 AM, Alex wrote:

On Friday, 18 January 2019 at 13:31:28 UTC, Steven Schveighoffer wrote:
To answer the OP, what he wants is an array of different 
RedBlackTrees. Since RedBlackTree is a class, his code is not far off 
from something that works. This does compile, and produces an Object[]:


    auto arr = [
 redBlackTree(Tuple!(int, "x", int, "y", string, "z")(1, 2, "abc")),
 redBlackTree(Tuple!(int, "x", int, "y", int, "z")(1, 2, 3))
];

Then you have to cast each object into it's appropriate type to use 
it. That is not as easy, as you have to know the exact instantiation 
of tree type.




In this case, I would say Phobos lacks an appropriate interface 
definition, what do you think?


But what is the common interface between those 2 types? Even in 
Dcollections, where RedBlackTree came from, there was no interfaces that 
didn't specify the type they were dealing with. In other words, there is 
no common interface for sets of 2 different types.


-Steve


Re: Runtime heterogeneous collections?

2019-01-18 Thread Alex via Digitalmars-d-learn
On Friday, 18 January 2019 at 13:31:28 UTC, Steven Schveighoffer 
wrote:
To answer the OP, what he wants is an array of different 
RedBlackTrees. Since RedBlackTree is a class, his code is not 
far off from something that works. This does compile, and 
produces an Object[]:


auto arr = [
 redBlackTree(Tuple!(int, "x", int, "y", string, "z")(1, 2, 
"abc")),

 redBlackTree(Tuple!(int, "x", int, "y", int, "z")(1, 2, 3))
];

Then you have to cast each object into it's appropriate type to 
use it. That is not as easy, as you have to know the exact 
instantiation of tree type.




In this case, I would say Phobos lacks an appropriate interface 
definition, what do you think?


Re: Runtime heterogeneous collections?

2019-01-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/17/19 11:06 PM, Jonathan M Davis wrote:

On Thursday, January 17, 2019 1:21:41 AM MST Dukc via Digitalmars-d-learn
wrote:

On Thursday, 17 January 2019 at 02:27:20 UTC, Neia Neutuladh

wrote:

1. Make a wrapper class. Now you can store Object[], or you can
make a
base class or base interface and use that.
2. Use Variant, which can wrap anything, or the related
Algebraic, which
can wrap a fixed collection of types.


3. Use an union. However, only do this if you always know from
outside what type of data is stored in each node. If you need to
memoize the type of data for each node, better resort to 1. or 2.


Variant types are really just user-friendly wrappers around unions. So,
pedantically, using a variant type such as Variant or Albegbraic and using a
union are fundamentally the same thing, though obviously, the actual usage
in terms of the code that you write is not the same, since if you use a
union directly, you have to deal with the union directly (including figuring
out how to know which type the union currently holds), whereas with a
Variant, you're using its API rather than dealing with the union directly.
In general, it's probably better to use Variant rather than union simply
because Variant deals with the type safety for you.



A variant is not a union. Algebraic is a union, but Variant can hold ANY 
type, even types your code doesn't know about.


To answer the OP, what he wants is an array of different RedBlackTrees. 
Since RedBlackTree is a class, his code is not far off from something 
that works. This does compile, and produces an Object[]:


auto arr = [
 redBlackTree(Tuple!(int, "x", int, "y", string, "z")(1, 2, "abc")),
 redBlackTree(Tuple!(int, "x", int, "y", int, "z")(1, 2, 3))
];

Then you have to cast each object into it's appropriate type to use it. 
That is not as easy, as you have to know the exact instantiation of tree 
type.


In this case, you are better off using a union, or an Algebraic as your 
array element type. If you use something like 
https://code.dlang.org/packages/taggedalgebraic it could be quite usable.


-Steve


Re: Runtime heterogeneous collections?

2019-01-17 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, January 17, 2019 1:21:41 AM MST Dukc via Digitalmars-d-learn 
wrote:
> On Thursday, 17 January 2019 at 02:27:20 UTC, Neia Neutuladh
>
> wrote:
> > 1. Make a wrapper class. Now you can store Object[], or you can
> > make a
> > base class or base interface and use that.
> > 2. Use Variant, which can wrap anything, or the related
> > Algebraic, which
> > can wrap a fixed collection of types.
>
> 3. Use an union. However, only do this if you always know from
> outside what type of data is stored in each node. If you need to
> memoize the type of data for each node, better resort to 1. or 2.

Variant types are really just user-friendly wrappers around unions. So,
pedantically, using a variant type such as Variant or Albegbraic and using a
union are fundamentally the same thing, though obviously, the actual usage
in terms of the code that you write is not the same, since if you use a
union directly, you have to deal with the union directly (including figuring
out how to know which type the union currently holds), whereas with a
Variant, you're using its API rather than dealing with the union directly.
In general, it's probably better to use Variant rather than union simply
because Variant deals with the type safety for you.

- Jonathan M Davis





Re: Runtime heterogeneous collections?

2019-01-17 Thread Seb via Digitalmars-d-learn
On Thursday, 17 January 2019 at 02:27:20 UTC, Neia Neutuladh 
wrote:

On Thu, 17 Jan 2019 02:21:21 +, Steven O wrote:
I want to create a heterogeneous collection of red-black 
trees, and I can't seem to figure out if it's possible.


RedBlackTree!int and RedBlackTree!string are entirely different 
types (they just happen to be generated from the same template).


There are two reasonable ways of doing things:

1. Make a wrapper class. Now you can store Object[], or you can 
make a

base class or base interface and use that.
2. Use Variant, which can wrap anything, or the related 
Algebraic, which

can wrap a fixed collection of types.

You can use this technique either with the collection types 
themselves or with the value types.


As the OP is most likely looking for Variant, let me link to it:

https://dlang.org/phobos/std_variant.html#Variant


Re: Runtime heterogeneous collections?

2019-01-17 Thread Dukc via Digitalmars-d-learn
On Thursday, 17 January 2019 at 02:27:20 UTC, Neia Neutuladh 
wrote:
1. Make a wrapper class. Now you can store Object[], or you can 
make a

base class or base interface and use that.
2. Use Variant, which can wrap anything, or the related 
Algebraic, which

can wrap a fixed collection of types.
3. Use an union. However, only do this if you always know from 
outside what type of data is stored in each node. If you need to 
memoize the type of data for each node, better resort to 1. or 2.





Re: Runtime heterogeneous collections?

2019-01-16 Thread Neia Neutuladh via Digitalmars-d-learn
On Thu, 17 Jan 2019 02:21:21 +, Steven O wrote:
> I want to create a heterogeneous collection of red-black trees, and I
> can't seem to figure out if it's possible.

RedBlackTree!int and RedBlackTree!string are entirely different types 
(they just happen to be generated from the same template).

There are two reasonable ways of doing things:

1. Make a wrapper class. Now you can store Object[], or you can make a 
base class or base interface and use that.
2. Use Variant, which can wrap anything, or the related Algebraic, which 
can wrap a fixed collection of types.

You can use this technique either with the collection types themselves or 
with the value types.


Runtime heterogeneous collections?

2019-01-16 Thread Steven O via Digitalmars-d-learn
I want to create a heterogeneous collection of red-black trees, 
and I can't seem to figure out if it's possible.


I can easily do:

import std.container.rbtree;
import std.typecons;

void main()
{
alias Rec_type = Tuple!(int, "x", int, "y", int, "z");
RedBlackTree!Rec_type[1] test;
}

That works great, but I can only add red-black trees of Rec_type. 
What if I want the collection of red-black trees to be different? 
So if you printed out the collection of red-black trees you'd see 
something akin to:


// Formatted for easier reading
[
 RedBlackTree([Tuple!(int, "x", int, "y", string, "z")(1, 2, 
"abc")]),

 RedBlackTree([Tuple!(int, "x", int, "y", int, "z")(1, 2, 3)])
]

Is it possible to do this?