digitalmars.D.learn - lambda recursion
- ddcovery (55/55) Nov 27 2020 I want to express in D the known Haskell qsort 3 lines code (it
- ddcovery (11/26) Nov 27 2020 I mean... transform this into a lambda expression:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/43) Nov 27 2020 filter!(i=3D> i >=3D items[0]).array)
- ddcovery (2/7) Nov 28 2020 Thanks Ali.
I want to express in D the known Haskell qsort 3 lines code (it is not a quick sort, but an example of how functional programming is expressive). This is the "javascript" version I use as reference: const sorted = ( [pivot, …others] ) => pivot===void 0 ? [ ] : [ … sorted( others.filter( n=> n<pivot ) ), pivot, … sorted( others.filter( n=> n>=pivot ) ) ]; This is a possible D implementation: void main() { import std.stdio, std.algorithm, std.range; int[] delegate(int[]) qs; qs = (int[] items) => items.length==0 ? items : chain( qs(items[1..$].filter!(i=> i<items[0] ).array), items[0..1], qs(items[1..$].filter!(i=> i >= items[0]).array) ).array; auto result = qs([10,9,5,4,8,7,-20]); assert( result.equal([-20,4,5,7,8,9,10]) ); writeln("Result:", result ); } First problem I found is "qs" must be splitted in 2 expressions: declaration and assignation, because declaration is not "effective" until all expression is compiled (compiler says qs doesn't exist when compiling the lambda body) . * Is there any way to reduce the code(using lambdas) to one expression only? int[] delegate(int[]) qs = (int[] items) => items.length==0 ..... Or better auto qs = (int[] items) => items.length==0 ? ... * Can the lambda be transformed to a template (using T instead "int") but avoiding function/return syntax? This is an example using function template qs(T){ T[] qs( T[] items ){ return items.length==0 ? items : chain( qs(items[1..$].filter!(i=> i<items[0] ).array), items[0..1], qs(items[1..$].filter!(i=> i >= items[0]).array) ).array; } } * I'm trying to use "ranges" to avoid the "array" conversion. Do you figure out a way to express the lambda params and return as a Range to avoid converting to array?
Nov 27 2020
On Friday, 27 November 2020 at 16:40:43 UTC, ddcovery wrote:... * Can the lambda be transformed to a template (using T instead "int") but avoiding function/return syntax? This is an example using function template qs(T){ T[] qs( T[] items ){ return items.length==0 ? items : chain( qs(items[1..$].filter!(i=> i<items[0] ).array), items[0..1], qs(items[1..$].filter!(i=> i >= items[0]).array) ).array; } }I mean... transform this into a lambda expression: T[] qs(T)( T[] items ){ return items.length==0 ? items : chain( qs(items[1..$].filter!(i=> i<items[0] ).array), items[0..1], qs(items[1..$].filter!(i=> i >= items[0]).array) ).array; }
Nov 27 2020
On 11/27/20 9:01 AM, ddcovery wrote:On Friday, 27 November 2020 at 16:40:43 UTC, ddcovery wrote:... * Can the lambda be transformed to a template (using T instead "int") =filter!(i=3D> i<items[0] ).array),but avoiding function/return syntax? This is an example using function =C2=A0 template qs(T){ =C2=A0=C2=A0=C2=A0 T[] qs( T[] items ){ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return items.length=3D=3D0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ? items =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : chain( =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 qs(items[1..$].=filter!(i=3D> i >=3D items[0]).array)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 items[0..1], =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 qs(items[1..$].=filter!(i=3D> i<items[0] ).array),=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ).array; =C2=A0=C2=A0=C2=A0 } }=20 I mean... transform this into a lambda expression: =20 =C2=A0=C2=A0=C2=A0 T[] qs(T)( T[] items ){ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return items.length=3D=3D0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ? items =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : chain( =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 qs(items[1..$].==C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 items[0..1], =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 qs(items[1..$].=filter!(i=3D> i >=3D items[0]).array)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ).array; =C2=A0=C2=A0=C2=A0 } =20This has been done with the Y-combinator, where the lambda refers to=20 itself as 'self': =20 https://github.com/gecko0307/atrium/blob/master/dlib/functional/combinato= rs.d There has been been other discussions on it on these forums. Ali
Nov 27 2020
On Friday, 27 November 2020 at 20:53:37 UTC, Ali Çehreli wrote:This has been done with the Y-combinator, where the lambda refers to itself as 'self': https://github.com/gecko0307/atrium/blob/master/dlib/functional/combinators.d There has been been other discussions on it on these forums. AliThanks Ali.
Nov 28 2020