Thread overview
function argument accepting function or delegate?
Jan 17, 2016
Jon D
Jan 17, 2016
rsw0x
Jan 17, 2016
Jon D
January 17, 2016
My underlying question is how to compose functions taking functions as arguments, while allowing the caller the flexibility to pass either a function or delegate.

Simply declaring an argument as either a function or delegate seems to prohibit the other. Overloading works. Are there better ways?

An example:

auto callIntFn (int function(int) f, int x) { return f(x); }
auto callIntDel (int delegate(int) f, int x) { return f(x); }
auto callIntFnOrDel (int delegate(int) f, int x) { return f(x); }
auto callIntFnOrDel (int function(int) f, int x) { return f(x); }

void main(string[] args) {
    alias AddN = int delegate(int);
    AddN makeAddN(int n) { return x => x + n; }

    auto addTwo = makeAddN(2);                // Delegate
    int function(int) addThree = x => x + 3;  // Function

    // assert(callIntFn(addTwo, 4) == 6);     // Compile error
    // assert(callIntDel(addThree, 4) == 7);  // Compile error
    assert(callIntDel(addTwo, 4) == 6);
    assert(callIntFn(addThree, 4) == 7);
    assert(callIntFnOrDel(addTwo, 4) == 6);
    assert(callIntFnOrDel(addThree, 4) == 7);
}

---Jon
January 17, 2016
On Sunday, 17 January 2016 at 06:27:41 UTC, Jon D wrote:
> My underlying question is how to compose functions taking functions as arguments, while allowing the caller the flexibility to pass either a function or delegate.
>
> [...]

Templates are an easy way.

---
auto call(F, Args...)(F fun, auto ref Args args) { return fun(args); }
---
Would probably look nicer with some constraints from std.traits.
January 17, 2016
On Sunday, 17 January 2016 at 06:49:23 UTC, rsw0x wrote:
> On Sunday, 17 January 2016 at 06:27:41 UTC, Jon D wrote:
>> My underlying question is how to compose functions taking functions as arguments, while allowing the caller the flexibility to pass either a function or delegate.
>>
>> [...]
>
> Templates are an easy way.
>
> ---
> auto call(F, Args...)(F fun, auto ref Args args) { return fun(args); }
> ---
> Would probably look nicer with some constraints from std.traits.

Thanks much, that works!
January 22, 2016
On 1/17/16 1:27 AM, Jon D wrote:
> My underlying question is how to compose functions taking functions as
> arguments, while allowing the caller the flexibility to pass either a
> function or delegate.
>
> Simply declaring an argument as either a function or delegate seems to
> prohibit the other. Overloading works. Are there better ways?

If you are looking for a runtime way to do this (the template alias way works too), you may look at std.functional.toDelegate which converts a function pointer to a delegate.

But it is awkward to make this a requirement for your user.

-Steve