Thread overview
How to reuse functions
May 01, 2015
Luigi
May 01, 2015
John Colvin
May 01, 2015
anonymous
May 02, 2015
Luigi
May 02, 2015
Luigi
May 01, 2015
Hi everybody.

I am tring to use a function where its parameter is another function, and at the same time are both already made - they cannot be modified - and the second one has to be conditioned before to be passed as argument.

Let's say I have these function and I cannot modify:

-jac(+d) that works on function and return real

real jac(real function(real) fun, real x) {return d(fun, x);}
real d(real function(real) fun, real x) {return fun(x);}

-F1 that works on two reals and return real

real F1(real a, real b) {return a + b;}

So I need a way to condition F1 fixing b and then pass it to jac as argument.

To do that I've created a delegate 'simp' conditionig F1:

real delegate(real) simp(real function(real, real) f, real x) {
	real _simp(real z) {
		return f(z, x);
		}
	return &_simp;
	}
(here 'simp' fixes b at x).

My main is:

void main() {
	real x_n = 1;
	real x_m = -1;
	real delegate(real) s_n = simp(&F1, x_n);
	//auto J = jac(s_n, x_m); //Error: function app.jac (real function(real) fun, real x) is not callable using argument types (real delegate(real), real)
	}

the code fails because jac expect as argument a function but I found only a delegate to obtain a simplified function without any touch at already made functions jac, d and F1.

There is a clean way to make it possible? I mean: without to touch (neither rewrite) jac, d and F1, obtain simplied F1 to pass to jac.

Thaks in advance to anyone could help me.
Luigi
May 01, 2015
On Friday, 1 May 2015 at 03:34:53 UTC, Luigi wrote:
> Hi everybody.
>
> I am tring to use a function where its parameter is another function, and at the same time are both already made - they cannot be modified - and the second one has to be conditioned before to be passed as argument.
>
> Let's say I have these function and I cannot modify:
>
> -jac(+d) that works on function and return real
>
> real jac(real function(real) fun, real x) {return d(fun, x);}
> real d(real function(real) fun, real x) {return fun(x);}
>
> -F1 that works on two reals and return real
>
> real F1(real a, real b) {return a + b;}
>
> So I need a way to condition F1 fixing b and then pass it to jac as argument.
>
> To do that I've created a delegate 'simp' conditionig F1:
>
> real delegate(real) simp(real function(real, real) f, real x) {
> 	real _simp(real z) {
> 		return f(z, x);
> 		}
> 	return &_simp;
> 	}
> (here 'simp' fixes b at x).
>
> My main is:
>
> void main() {
> 	real x_n = 1;
> 	real x_m = -1;
> 	real delegate(real) s_n = simp(&F1, x_n);
> 	//auto J = jac(s_n, x_m); //Error: function app.jac (real function(real) fun, real x) is not callable using argument types (real delegate(real), real)
> 	}
>
> the code fails because jac expect as argument a function but I found only a delegate to obtain a simplified function without any touch at already made functions jac, d and F1.
>
> There is a clean way to make it possible? I mean: without to touch (neither rewrite) jac, d and F1, obtain simplied F1 to pass to jac.
>
> Thaks in advance to anyone could help me.
> Luigi

A combination of std.functional.reverseArgs and std.functional.partial might help. It's unfortunately we don't have a version that can set an arbitrary argument, only the first one; It would be an easy improvement to make.
May 01, 2015
On Friday, 1 May 2015 at 03:34:53 UTC, Luigi wrote:
> Hi everybody.
>
> I am tring to use a function where its parameter is another function, and at the same time are both already made - they cannot be modified - and the second one has to be conditioned before to be passed as argument.
>
> Let's say I have these function and I cannot modify:
>
> -jac(+d) that works on function and return real
>
> real jac(real function(real) fun, real x) {return d(fun, x);}
> real d(real function(real) fun, real x) {return fun(x);}
>
> -F1 that works on two reals and return real
>
> real F1(real a, real b) {return a + b;}
>
> So I need a way to condition F1 fixing b and then pass it to jac as argument.
>
> To do that I've created a delegate 'simp' conditionig F1:
>
> real delegate(real) simp(real function(real, real) f, real x) {
> 	real _simp(real z) {
> 		return f(z, x);
> 		}
> 	return &_simp;
> 	}
> (here 'simp' fixes b at x).
>
> My main is:
>
> void main() {
> 	real x_n = 1;
> 	real x_m = -1;
> 	real delegate(real) s_n = simp(&F1, x_n);
> 	//auto J = jac(s_n, x_m); //Error: function app.jac (real function(real) fun, real x) is not callable using argument types (real delegate(real), real)
> 	}
>
> the code fails because jac expect as argument a function but I found only a delegate to obtain a simplified function without any touch at already made functions jac, d and F1.
>
> There is a clean way to make it possible? I mean: without to touch (neither rewrite) jac, d and F1, obtain simplied F1 to pass to jac.

If x_n is a constant (enum), you can use that to create a function instead of a delegate:

----
void main() {
    enum real x_n = 1;
    real x_m = -1;
    real function(real) s_n = z => F1(z, x_n);
    auto J = jac(s_n, x_m);
}
----

If x_n is not constant, then the only way I see to make this work, is to use a module variable:

----
real x_n;
void main() {
    x_n = 1;
    real x_m = -1;
    real function(real) s_n = z => F1(z, x_n);
    auto J = jac(s_n, x_m);
}
----
May 02, 2015
On Friday, 1 May 2015 at 11:03:19 UTC, anonymous wrote:
> If x_n is a constant (enum), you can use that to create a function instead of a delegate:
>
> ----
> void main() {
>     enum real x_n = 1;
>     real x_m = -1;
>     real function(real) s_n = z => F1(z, x_n);
>     auto J = jac(s_n, x_m);
> }
> ----
>
> If x_n is not constant, then the only way I see to make this work, is to use a module variable:
>
> ----
> real x_n;
> void main() {
>     x_n = 1;
>     real x_m = -1;
>     real function(real) s_n = z => F1(z, x_n);
>     auto J = jac(s_n, x_m);
> }
> ----

On Friday, 1 May 2015 at 06:48:46 UTC, John Colvin wrote:
> A combination of std.functional.reverseArgs and std.functional.partial might help. It's unfortunately we don't have a version that can set an arbitrary argument, only the first one; It would be an easy improvement to make.

Thank you both. I understood what you have shown to me.
About the chain 'reverseArg'+'partial' I reached to use it partially, only the partial part; so it worked with exception of reverseArg. I made several attempt to make it working but without succes.

About the scope/declaration suggestion they worked, fine. I've also made a change declaring x_s as static and worked as well (without change of scope and without use of enum).

Unfortunatly I tried to exted the code by introducing array of functions F1->[F1, F2, ...] and I saw such solution cannot apply. That why because of built functions passed (as example) to lambda function they do not store information. And I went back to delegates that store the necessary data to create the correct function. I've seen some method to pass from delegates to function, but onestly I found a to complex approach and much more a workaround that a good programming.
Going back to my study of D I will find the right way of thinking to approch such problems (I imagine now the trick could be using templates... I will see).

Thanks again. I've learned many things by looking at you solution.
May 02, 2015
ERRATA CORRIGE:
in place of x_s replace with x_n.
Sorry