Decorators, Annotations, Macros, AST transforms…
Dicebot
public at dicebot.lv
Tue Feb 4 04:31:23 PST 2014
There is no such thing as transformation of existing entity on
compile-time in D. Despite having similar syntax Python
decorators don't really have much in common with User-Defined
Attributes. Attributes can never change symbol/type they are
attached to, they only represent additional information available
at compile-time.
Right now idiomatic D way to do such thing is via two-step
declaration and mixin:
```pythonEntry.d
private string generateFromImpl(alias func)()
{
import std.string : format;
import std.array : join;
import std.traits : ParameterIdentifierTuple;
string code;
// signature
code ~= "extern(C) ";
code ~= cloneFunctionDeclaration!func(
__traits(identifier, func)[$-4, $] // new name, XImpl -> X
);
// body
code ~= format(
q{
{
initializeIfNoAlreadyDone();
%s(%s);
}
},
fullyQualifiedName!func,
[ ParameterIdentifierTuple!func ].join(",")
);
}
public mixin template pythonEntry(alias func)
{
mixin(generateFromImpl!func());
}
```
```main.d
import pythonEntry;
auto nameImpl() {
// ...
}
mixin pythonEntry!nameImpl; // will add `name` function you want
```
As you can see it is not very obvious. In practice it is even
much more complicated as I have skipped implementation of
cloneFunctionDeclaration - one that I use for vibe.d takes quite
a lot of space -
https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/internal/meta/codegen.d#L177
One can also use module introspection + UDA to automatically do
such mixin for all function attrbiuted with @pythonentry but it
is even more code so I'd prefer to not paste it here :)
Unfortunately Phobos is currently lacking some very common code
generation helpers used in idiomatic D metaprogramming. I plan to
work on improvements in that direction after tuple situation is
taken care of.
P.S. If my talk proposal for DConf is going to be accepted, it
will cover this very topic, extensively :P
More information about the Digitalmars-d-learn
mailing list