November 20, 2016
When using functions with delegate (or function ptr) parameters which should comply with some attributes, I cannot call the delegate in the function what makes it pretty useless (I haven't done research, but I claim that generally most functions taking delegate parameters call them).

  void f1(void delegate(int) dg) // cannot be pure ...
  {
    dg(1); // ... due to this call.
  }

  void main() pure
  {
    f(x => 2*x); // Error, f is impure.
  }

One has to overload the function like
  auto f(delegate(Arg arg) @attrib dg) @attrib;
  auto f(delegate(Arg arg)         dg);
for each combination of attributes available (today 4, worst case is 16 overloads), could be more in the future.

Even worse (due to bug 15859, see [1]) overload resolution on opApply does not work properly. Making opApply a template is a real solution for various reasons (virtual functions, no type inference on the delegate, etc.). For opApply, using the range interface (empty, front, popFront) is not a real solutions either because opApply can be truly recursive. Those can then only have a range interface through generators via fibers which have an overhead (and make them non-@nogc).

How can I have relative-@attrib functions without unnecessary manual overloading?
(relative: if all called parameter delegates have it, then the function has it)

Generally, are relative attributes worth an enhancement?

[1] https://issues.dlang.org/show_bug.cgi?id=15859
November 20, 2016
On Sunday, 20 November 2016 at 16:36:18 UTC, Q. Schroll wrote:
> How can I have relative-@attrib functions without unnecessary manual overloading?


import std.traits;

auto f1(DG) (DG dg) if (isCallable!DG && Parameters!DG.length == 1 && is(Parameters!DG[0] == int)) { // check other things here too, like return type
  return dg(1);
}

void main () pure {
  f1((int x) => 2*x); // ok, f1 is pure
  //f1(x => 2*x); // alas, now you have to manually specify argument types
}


not the best solution, of course, and you can't do that without templates ('cause `nothrow` or `@nogc` *can* require different machine code in the future).