Eponymous/anonymous mixin templates

Jeffrey Tsang via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 8 13:05:01 PDT 2015


On Monday, 8 June 2015 at 20:04:00 UTC, Jeffrey Tsang wrote:
> On Monday, 8 June 2015 at 16:27:36 UTC, Artur Skawina wrote:
>> On 06/08/15 17:14, Jeffrey Tsang via Digitalmars-d wrote:
>>> On Sunday, 7 June 2015 at 14:17:45 UTC, Artur Skawina wrote:
>>>> On 06/07/15 11:05, Jeffrey Tsang via Digitalmars-d wrote:
>>>>> I use a mixin template to define exactly one symbol, and at 
>>>>> instantiation I wish to use that symbol immediately, once.
>>>>
>>>> AFAICT you're asking for the commented-out line in
>>>>
>>>>   auto Tmpl() = l;
>>>>
>>>>   void main(string[] argv) {
>>>>      auto l = argv.length;
>>>>      mixin Tmpl!() a;
>>>>      assert(a.Tmpl==l);
>>>>      //assert(a==l);
>>>>   }
>>>>
>>>> to work. That would probably be enough, make sense and have
>>>> no serious backward compat issues.
>>> 
>>> There are three separate things I would like to have:
>>> 
>>> 1. Eponymous trick
>>> 
>>> mixin T foo(T)() {
>>>    return bar;
>>> }
>>> 
>>> as pure syntactic sugar for
>>> 
>>> mixin template foo(T) {
>>>    T foo() {
>>>        return bar;
>>>    }
>>> }
>>
>> This part already works, if you leave out the 'mixin' 
>> annotation
>> (which only prevents non-mixin use). "Normal" templates can be
>> mixed in too, see my `Tmpl` example above.
>>
>>   T foo(T)() {
>>      return bar;
>>   }
>>
>>   auto f(int bar) {
>>      mixin foo!double blah;
>>      return blah.foo();
>>   }
>>
>>   void main() {
>>      assert (f(42)==42.0);
>>   }
>>
>
> Recursive mixin templates, which is mostly the reason I'm using 
> this, won't work:
>
> string foo(string x)() {
>     return x;
> }
>
> string foo(string x, T...)() {
>     mixin foo!T _foo;
>     return x ~ y ~ _foo.foo();
> }
>
> // mixin foo!("a", "b"); // dies on foo not a template
>
>>> 2. Eponymous trick, calling end
>>> 
>>> mixin foo!T;
>>> 
>>> to also include as syntactic support
>>> 
>>> alias foo = foo!T.foo;
>>> 
>>> as well as the named version you listed.
>>
>> No, that would hide the `foo` template symbol.
>> There's no such problem with the named version (other than
>> the eponymous look-up not working).
>>
> I just mean the eponymous look-up part of it, whatever the 
> compiler-generated alias looks like.
>
>>> 3. Inline/anonymous mixins
>>> 
>>> Some way of writing the equivalent of
>>> 
>>> bar = (mixin foo!T)() + 3;
>>
>> This part I'm not sure about. Can't think of an interesting
>> use case, that wouldn't be better handled in some other way.
>> The obvious workaround would be:
>> 
>>   bar = { mixin foo!T f; return f()+3; }(); // today: 
>> `f.foo()+3`
>>
>> [`{...}()` might result in a lambda/closure right now, but that
>> should really be fixed (ie defined as a special case)]
>>
>> artur
>> 
>
> Yeah, it's probably easier to do
>
> auto foo = { mixin foo!T f; return f.foo; }()
>
> and take one name. With the mixin using enclosing scope, can it 
> be function and not delegate?

I meant
auto foo = { mixin foo!T f; return &f.foo; }();
and then use the function normally.


More information about the Digitalmars-d mailing list