[phobos] phobos commit, revision 1737

Andrei Alexandrescu andrei at erdani.com
Thu Jul 8 10:18:45 PDT 2010


On 07/08/2010 09:28 AM, Shin Fujishiro wrote:
> I too think that these features should be in Algebraic.

Excellent!

> Actually, I created Any because Algebraic did not support dispatching
> and copy constructing.  I did not touch Algebraic because it was
> rather difficult to implement opDispatch to the backing VariantN.
>
> Then, may I integrate Any into Algebraic?  The interface will be
> changed:
>
> Algebraic!(short, int) x;
> x.allowed!int	-->	x.Algebraic.allowed!int
> x.hasValue	-->	x.Algebraic.empty
> x.peek!int	-->	&(x.Algebraic.instance!int())

Yes, absolutely. Your design is much better because it avoids hiding 
e.g. "allowed" in some hosted type with its own "allowed". This will 
become, I suspect, a gold standard for D types that define opDispatch or 
alias this.

As you sure have noticed and as Michel pointed out, putting your stuff 
into Algebraic might be a bit difficult. The design is simple, but the 
implementation is quite hard to follow and relies on pointer to 
implementation instead of index into implementation table. (Variant must 
use pointer to implementation because it supports unbounded types.)

If you find it necessary to completely divorce the Variant 
implementation from the Algebraic implementation, please do so.

Finally, a suggestion: I have hoped to find time to define opDispatch 
for Variant. It should accept template variadics and dynamically 
dispatch the call to the supported type if compatible, or throw an 
exception otherwise. It's the dynamic counterpart of your opDispatch.

Example:

class A { double foo(int x) { return 1.0 / x; } }
auto v = Variant(new A);
Variant result = v.foo(2);
assert(result.Variant.get!double() == 0.5);

Internally, Variant would need to store a hashtable keyed by method name 
with method information (parameter types, result type, pointer to invoker).

I think it's entirely possible to do that with what we have now, modulo 
some small glitches in static reflection implementation. Once we have 
that, we're really talking dynamic - like Python or Ruby dynamic.

>> P.S. I *love* the trick with the homonym inner namespace! It solves the
>> naming problem so elegantly. I'll use it in RefCounted too.
>
> It was a bit surprising for me that the inner template could access
> member variables without being mixed in.  But I found that it's just
> another "template member function", and so it's legal. :-)

BTW here's what I did in RefCounted:

struct RefCounted(T)
{
     struct _RefCounted
     {
         ... stuff ...
     }
     _RefCounted RefCounted;
     ... constructor, postblit, destructor, opAssign ...
}

Seems to work fine.


Andrei


More information about the phobos mailing list