std.mixins

dsimcha dsimcha at yahoo.com
Tue Aug 31 14:49:43 PDT 2010


== Quote from Philippe Sigaud (philippe.sigaud at gmail.com)'s article
> std.typecons is full of good stuff. I learnt quite a lot reading it. The Any
> code gave many hours of reading, compiling the resulting code in my head, so
> to say. Then I went a little mad ;)
> My initial suggestion for your OP was a mixin to put in a class/struct to
> make it extensible: using opDispatch to transform a method call
> a.foo(args...) into the free function foo(a, args). That way a library
> author makes her class extensible, and I, as a user, add free
> functions-passing-as-methods as I see fit.
> template MakeExtensible()
> {
>     auto opDispatch(string s, Args...)(Args args)
> if(is(typeof(mixin(s~"(this, args)"))))
>     {
>        mixin("return "~s~"(this, args);");
>     }
> }
> It's a 3-line mixin, but it suffers from a nasty problem: opDispatch only
> sees the symbols defined in the class modules, which forces the user to
> define the free functions in the class module and that rather defeats the
> point :(
> The only solution I found was to make a wrapper template: struct (or class)
> Extend!Type that will act as a Type in most cases and uses an opDispatch to
> remain open. Note that 'alias this' has priority on opDispatch, so I
> couldn't use alias this in this case: the free-functions-as-method calls
> would be propagated to the wrapped struct/class and create an error there,
> without being rerouted through opDispatch.
> Anyway...
> To solve the symbol-visibility problem, I made the whole machinery a
> template, which should be mixed in the main module.
> For the user, it's trivial, add:
> mixin Extensible;
> in your main module (or in any module you'll use free functions, but symbol
> visibility will be affected ). You can then use extend(value) to get an
> extensible version of a class or struct.
> I have to complete to code to forward all operator calls to the wrapped
> value, since I cannot use alias this. In the end, I project to extract this
> part to make a generic ParallelType!Type wrapper that is not a subtype of
> Type (as alias this would). Indeed ExtendType is just a parallel type wich
> forward unknown methods to free functions.
> Another proposal I have is a mixin that creates a string enum, Names,
> containing the local scope qualified name.
> module pack.mod;
> mixin(ScopeName); // Names is "pack.mod"
> int foo(int j)
> {
> mixin(ScopeName); // Names is "pack.mod.foo"
> }
> class C(A,B)
> {
>     struct S
>     {
>         void method()
>         {
>         mixin(ScopeName); // Once C is instantiated Names is
> "pack.mod.C!(type1, type2).S.method"
>         }
>     }
> }

Isn't this a core language feature that's in the spec but is only currently
implemented for arrays?  I thought eventually uniform function call syntax was
coming for classes and structs, too.


More information about the Digitalmars-d mailing list