Mixin templates are a pain at best, useless at worst for any non-trivial use case
Simen Kjærås
simen.kjaras at gmail.com
Tue Jun 5 12:08:58 UTC 2018
On Tuesday, 5 June 2018 at 10:11:49 UTC, Ethan wrote:
> Exhibit A: https://run.dlang.io/is/a85Lbq
>
> I submitted a bug with the above code, and it was "helpfully"
> shut down with a link to the documentation and workaround.
> Congratulations. That's not the use case here, and to be quite
> honest this is one of those examples where a #define macro
> would "just work". And I'm firmly of the view that *ANY*
> example of that should be dealt with at a language level in
> order to completely remove the argument of needing a
> preprocessor.
There's a reason for those rules in the language, namely function
hijacking. This is an issue we take very seriously, and
workarounds exists.
As you point out, the suggested workaround is aliasing each
function in the mixin (you also say you don't want workarounds -
bear with me, I'm building to a point). This can to some extent
be encapsulated in a string mixin that's used alongside any
template mixin:
string introduceSymbols(alias F)()
{
enum id = __traits(identifier, F);
return "static foreach (fn; __traits(allMembers, "~id~")) {"~
" mixin(`alias `~fn~` = "~id~".`~fn~`;`);"~
"}";
}
mixin foo!() foo_;
mixin(introduceSymbols!foo_);
This introduces complexity in that each mixin must be given a
unique name at instantiation, another line must be included with
every mixin, and the name must be repeated in the second line.
This situation is less than optimal, and the compiler gives no
help if you've forgotten a introduceSymbols line, or passed it
the wrong name.
These issues can be ameliorated as in your other post here, by
wrapping the template mixin statement as well. This leads to a
host of other problems - how do you specify arguments to the
mixin template? How do you deal with aliased mixin templates?
These issues may possibly be fixed, but it's gonna get ugly.
Can we perhaps do better? Could we somehow say at the
instantiation point 'please introduce all symbols in this mixin
into the instantiation scope even if there are hijackings.'?
Something like `mixin scope foo!();`? That seems possible to me.
If we write a DIP for it, I've a good feeling about getting that
into the language.
This issue shows up every now and then, so we know it's a real
issue, and the workarounds are clunky. At the same time, the
current behavior is there for a reason, and is very unlikely to
change.
--
Simen
More information about the Digitalmars-d
mailing list