is(x = module) vs. __traits(isModule, x)

Paul Backus snarwin at gmail.com
Wed Oct 7 20:58:21 UTC 2020


On Wednesday, 7 October 2020 at 20:37:47 UTC, Meta wrote:
> On Wednesday, 7 October 2020 at 20:19:57 UTC, Paul Backus wrote:
>> Couldn't you unconditionally lower <Node>.__isModule to 
>> __traits(isModule, <Node>) regardless of what type of node it 
>> is, and rely on the existing error messages for incorrect 
>> trait arguments? You don't have to worry about shadowing 
>> "real" properties, because anything that starts with "__" is a 
>> reserved identifier.
>
> struct Wrapper(alias sym)
> {
>     import std.format: format;
>
>     template opDispatch(string name, Args...)
>     //Not DRY, probably a better way to do this
>     if (__traits(compiles, mixin(`__traits(%s, sym, 
> Args)`.format(name))))
>     {
>         enum opDispatch = mixin(`__traits(%s, sym, 
> Args)`.format(name));
>     }
> }
>
> void main()
> {
> 	import std.stdio;
>
>     writeln(Wrapper!(std).isPackage);
> }

Clever. Now try this:

     writeln(Wrapper!("hello" + 1).compiles);

Or this:

     struct S { int x; }
     int n = 123;
     writeln(Wrapper!(S(n)).getMember!"x");

Or this:

     struct S { in x, y; }
     writeln(Wrapper!S.allMembers);

The problem with using templates to wrap __traits is that 
__traits can do things that templates aren't allowed to do, like 
take expressions as arguments, or evaluate to expressions rather 
than symbols or constants.


More information about the Digitalmars-d mailing list