Re: Function Composition
On Monday, 29 January 2024 at 19:24:51 UTC, Inkrementator wrote: On Thursday, 25 January 2024 at 18:44:26 UTC, atzensepp wrote: However this works: ```d int delegate (int) td = (x) => compose!(f,g,g,f,g,g,f,g,g,f)(x); ``` While not a real function pointer, this might already fit your needs. ```d alias td = compose!(f,g); ``` Dear Inkrementator, thank you very much for this recommendation! This is an effective way to make functions and delegates compatible.
Re: Function Composition
On Thursday, 25 January 2024 at 18:44:26 UTC, atzensepp wrote: However this works: ```d int delegate (int) td = (x) => compose!(f,g,g,f,g,g,f,g,g,f)(x); ``` While not a real function pointer, this might already fit your needs. ```d alias td = compose!(f,g); ```
Re: Function Composition
On Thursday, 25 January 2024 at 12:19:47 UTC, Paul Backus wrote: On Thursday, 25 January 2024 at 08:25:02 UTC, atzensepp wrote: ```d int function(int) t = compose!(f,g,g,f,g,g,f,g,g,f); ``` This leads to: ``` gdc lambda4.d lambda4.d:28:25: error: template compose(E)(E a) has no value int function(int) t = compose!(f,g,g,f,g,g,f,g,g,f); ``` Try using the address operator: // Here //▼ int function(int) t = !(f,g,g,f,g,g,f,g,g,f); Hello, thanks for the hint. But in my environment I am getting the same error: ``` gdc lambda4.d lambda4.d:29:26: error: compose(E)(E a) is not an lvalue int function(int) t = !(f,g,g,f,g,g,f,g,g,f); ``` However this works: ```d int delegate (int) td = (x) => compose!(f,g,g,f,g,g,f,g,g,f)(x); ```
Re: Function Composition
On Thursday, 25 January 2024 at 08:25:02 UTC, atzensepp wrote: ```d int function(int) t = compose!(f,g,g,f,g,g,f,g,g,f); ``` This leads to: ``` gdc lambda4.d lambda4.d:28:25: error: template compose(E)(E a) has no value int function(int) t = compose!(f,g,g,f,g,g,f,g,g,f); ``` Try using the address operator: // Here //▼ int function(int) t = !(f,g,g,f,g,g,f,g,g,f);
Re: Function Composition
On Wednesday, 24 January 2024 at 21:34:26 UTC, user1234 wrote: On Wednesday, 24 January 2024 at 21:30:23 UTC, user1234 wrote: On Wednesday, 24 January 2024 at 21:12:20 UTC, atzensepp wrote: [...] what a bummer! Have you tried https://dlang.org/phobos/std_functional.html#compose ? Well this violates the second requirement: the composition itself requires additional lambda expressions I would like to write compose(f,g) I just realize, as this requires template specialization with `!`. But this is how D works with these kind of things. Hello, thank you for pointing me to compose! I think i can live with intermediate lambda expression as it is hidden in the template. Obviously functions and delegates are different kinds. And compose from std.functional is excellent as it has varargs and is also very generic. The only rest issue is that I do not know how to get a pointer to composed function. ```d int main() { writeln(compose!(map!(to!(int)), split)("1 2 3").equal([1, 2, 3])); writeln( compose!(f,g,g,f,g,g,f,g,g,f)(8)); int function(int) t = compose!(f,g,g,f,g,g,f,g,g,f); writeln(t(3)); // auto cf = curry!f; // auto cf1 = cf(1); // auto cf2 = cf(2); return(0); } ``` This leads to: ``` gdc lambda4.d lambda4.d:28:25: error: template compose(E)(E a) has no value int function(int) t = compose!(f,g,g,f,g,g,f,g,g,f); ```
Re: Function Composition
On Wednesday, 24 January 2024 at 21:30:23 UTC, user1234 wrote: On Wednesday, 24 January 2024 at 21:12:20 UTC, atzensepp wrote: [...] what a bummer! Have you tried https://dlang.org/phobos/std_functional.html#compose ? Well this violates the second requirement: the composition itself requires additional lambda expressions I would like to write compose(f,g) I just realize, as this requires template specialization with `!`. But this is how D works with these kind of things.
Re: Function Composition
On Wednesday, 24 January 2024 at 21:12:20 UTC, atzensepp wrote: [...] what a bummer! Have you tried https://dlang.org/phobos/std_functional.html#compose ?
Re: Function Composition
Some progress: compose function needs to know type but templates help to create for different types. ```d import std.stdio; import std.container.array; // Function composition: int f(int x) { return x*2;} ; int g(int x) { return x+2;} ; double ff(double x) { return x*x;} ; double gg(double x) { return 2+x;} ; template Delegate(T) { T delegate(T) compose( T function(T)second, T function(T )first) { return ((T i) => second(first(i))); } } void main() { alias c = Delegate!(int); writeln( c.compose(,)(2)); writeln( c.compose(,)(2)); alias d = Delegate!(double); writeln( d.compose(,)(2)); writeln( d.compose(,)(2)); } ``` Compose function gets 2 pointers to functions and yield a delegate. The created delegate can be invoked. However it cannot be passed to the composition function. This: ```d int delegate (int) fg = c.compose(,); int delegate (int) fgf = c.compose(fg,); writeln( fgf(2)); ``` leads to: ``` lambda2.d:41:37: error: function lambda2.Delegate!int.compose (int function(int) second, int function(int) first) is not callable using argument types (int delegate(int), int function(int x)) int delegate (int) fgf = c.compose(fg,); ``` what a bummer!
Function Composition
How is it possible to compose functions? I came up with following solution that is not satisfactory for two reasons: 1. the compose function should be argument agnostic here it is explicitly coded for (int) -> (int) 2. the composition itself requires additional lambda expressions I would like to write compose(f,g) ```dimport std.stdio; // Function composition: int f(int x) { return x*2;} ; int g(int x) { return x+2;} ; int delegate (int) compose( int delegate(int)second, int delegate(int)first) { return ((int i) => second(first(i))); } void main() { writeln( compose((x) => f(x),(x) => g(x))(2)); writeln( compose((x) => g(x),(x) => f(x))(2)); } ~ ~ ~ ```