Thread overview
why no statements inside mixin teplates?
May 12, 2017
visitor
May 12, 2017
Andrea Fontana
May 12, 2017
visitor
Jul 27, 2017
Domain
Jul 27, 2017
John Colvin
May 12, 2017
Is there a rational behind not allowing statements inside mixin templates? I know mixin does accept code containing statements, but using mixin is much uglier. so  I was wondering.

example use case:
//---------------------------------
int compute(string)
{
    return 1;
}

mixin template testBoilerPlate(alias arg, alias expected)
{
    {
        import std.format : format;
        auto got = compute(arg);
        assert(got == expected, "expected %s got %s".format(expected, got));
    }
}

unittest
{
    mixin testBoilerPlate("12345", 1);
    mixin testBoilerPlate("00" ~ "0", 2 - 1);
}
//--------------------------------
May 12, 2017
On Friday, 12 May 2017 at 00:20:13 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:
> Is there a rational behind not allowing statements inside mixin templates? I know mixin does accept code containing statements, but using mixin is much uglier. so  I was wondering.
>
> example use case:
> //---------------------------------
> int compute(string)
> {
>     return 1;
> }
>
> mixin template testBoilerPlate(alias arg, alias expected)
> {
>     {
>         import std.format : format;
>         auto got = compute(arg);
>         assert(got == expected, "expected %s got %s".format(expected, got));
>     }
> }
>
> unittest
> {
>     mixin testBoilerPlate("12345", 1);
>     mixin testBoilerPlate("00" ~ "0", 2 - 1);
> }
> //--------------------------------

On Friday, 12 May 2017 at 00:20:13 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:

works for me :
mixin template testBoilerPlate(alias arg, alias expected)
{
    auto doit = {
        import std.format : format;
        auto got = compute(arg);
        assert(got == expected, "expected %s got %s".format(expected, got));
        return true;
    }();
}
May 12, 2017
On Friday, 12 May 2017 at 08:47:32 UTC, visitor wrote:
> works for me :
> mixin template testBoilerPlate(alias arg, alias expected)
> {
>     auto doit = {
>         import std.format : format;
>         auto got = compute(arg);
>         assert(got == expected, "expected %s got %s".format(expected, got));
>         return true;
>     }();
> }

Another error: you want to invoke mixin with testBoilerPlate!(...) not testBoilerPlate();

May 12, 2017
On Friday, 12 May 2017 at 09:02:25 UTC, Andrea Fontana wrote:
> Another error: you want to invoke mixin with testBoilerPlate!(...) not testBoilerPlate();

yes, forgot to add it ...

May 12, 2017
On Friday, 12 May 2017 at 08:47:32 UTC, visitor wrote:
> works for me :
> mixin template testBoilerPlate(alias arg, alias expected)
> {
>     auto doit = {
>         import std.format : format;
>         auto got = compute(arg);
>         assert(got == expected, "expected %s got %s".format(expected, got));
>         return true;
>     }();
> }

nice hack, or should I say idiom? I definitely didn't think of that one, I though of  using a parameterized function which kinda similar. but this isn't what I'm looking for.I just want to do C style macro expansion. no function/lambda call at runtime, even if the optimizer inlines the lambda's. I can do this with plain mixin, but it's uglier.

example with mixin:
//-----------------------
string testBoilerPlate(alias arg, alias expected)()
{
    import std.format : format;

    return q{
        {
            import std.format : format;
            auto got = compute(%1$s);
            assert(%2$s == got, "expected %%s, got %%s".format(%2$s, got));
        }
    }.format(arg.stringof, expected.stringof);
}

unittest
{
    mixin(testBoilerPate!("000", 1));
}
//-----------------------
May 12, 2017
On Friday, 12 May 2017 at 00:20:13 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:
> Is there a rational behind not allowing statements inside mixin templates? ...

I guess the answer is, nobody has written a DIP for it?
July 27, 2017
On Friday, 12 May 2017 at 20:51:17 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:
> On Friday, 12 May 2017 at 00:20:13 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:
>> Is there a rational behind not allowing statements inside mixin templates? ...
>
> I guess the answer is, nobody has written a DIP for it?

I am also wondering why, this is a very useful feature. Now I have to use string mixin hack.
July 27, 2017
On Friday, 12 May 2017 at 00:20:13 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:
> Is there a rational behind not allowing statements inside mixin templates? I know mixin does accept code containing statements, but using mixin is much uglier. so  I was wondering.
>
> example use case:
> //---------------------------------
> int compute(string)
> {
>     return 1;
> }
>
> mixin template testBoilerPlate(alias arg, alias expected)
> {
>     {
>         import std.format : format;
>         auto got = compute(arg);
>         assert(got == expected, "expected %s got %s".format(expected, got));
>     }
> }
>
> unittest
> {
>     mixin testBoilerPlate("12345", 1);
>     mixin testBoilerPlate("00" ~ "0", 2 - 1);
> }
> //--------------------------------

If you can put up with the limitation of what can be done in a nested function then this convention works (choose whatever names you want, A and __ are just for example):

mixin template A()
{
	auto __()
	{
		++a;
	}
}

void main()
{
	int a = 0;

	mixin A!() __; __.__;

	assert (a == 1);
}