Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
May 01, 2015 How to reuse functions | ||||
---|---|---|---|---|
| ||||
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 Re: How to reuse functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luigi | 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 Re: How to reuse functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luigi | 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 Re: How to reuse functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | 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. |
Copyright © 1999-2021 by the D Language Foundation