News for hackers. Stuff that matters.
Re:Wc in D: 712 Characters Without a Single Branch by acehreli on Tuesday January 28, 2020 @01:23PM (#22172417)
Spot on! :) With the help of opDispatch (the catch-all member function temlate), it's possible to drop the string from the use site. (I don't know a way of dropping it from the type name.)

  import std.stdio;
  import std.typecons;
  import std.string;
  
  // This type's opDispatch removes the need for string in the flag name.
  struct FlagFromBool {
    auto opDispatch(string flagName)(bool value) {
      mixin (format!q{
        return value ? Yes.%s : No.%s;
      }(flagName, flagName));
    }
  }
  
  // A convenience function to remove the need for empty struct construction parenthesis.
  auto flagFromBool() {
    return FlagFromBool();
  }
  
  // Unfortunately, the type name still requires string flag names:
  void bar(Flag!"foo" flag) {
    writeln("called with ", flag);
  }
  
  void main() {
    // However, the expressions don't need a string:
    bar(flagFromBool.foo(false));
    bar(flagFromBool.foo(true));
  }
Re:Wc in D: 712 Characters Without a Single Branch by biotronic on Wednesday January 29, 2020 @03:07AM (#22178434)
Both your convenience function and the quotes in the type name can be removed via the use of static opDispatch:

struct FlagImpl(string name) { bool value; alias value this; }

struct Flag { alias opDispatch(string name) = FlagImpl!name; }

struct Yes { static auto opDispatch(string name)() { return FlagImpl!name(true); } }

struct No { static auto opDispatch(string name)() { return FlagImpl!name(false); } }

void fun(Flag.foo a) {} // Look ma, no quotes!

unittest { fun(Yes.foo); fun(Flag.foo(true)); }