On Monday, 22 August 2022 at 15:15:22 UTC, Paul Backus wrote:
My first instinct is to say that this is the user's mistake.
UDAs are not evaluated like normal expressions, and anyone
using UDAs is going to have to learn that sooner or later.
My feeling was that UDA expression is just an expression that's
evaluated at compile time. Am I wrong? Where can I read about the
differences between UDA and 'normal' expressions?
That said, if you want to try and present a nicer API, my
recommendation would be to accept *either* (a) an instance of
`U`, or (b) a callable that returns a `U`, which you can do
with code like the following:
```d
import std.traits, std.meta;
enum isOrReturnsU(alias attr) = is(typeof(attr) == U) ||
is(typeof(attr()) == U);
alias getMyUDAs(alias sym) = Filter!(isOrReturnsU, getUDAs!sym);
```
Or if you want to generalize to arbitrary predicates:
```d
alias filterUDAs(alias sym, alias pred) = Filter!(pred,
getUDAs!sym);
```
Thanks for this suggestion, I'll try it out!