www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using opApply and Attributes

reply Q. Schroll <qs.il.paperinik gmail.com> writes:
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
Nov 20 2016
parent ketmar <ketmar ketmar.no-ip.org> writes:
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).
Nov 20 2016