www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Recursive lambda functions?

reply "Ilya Yaroshenko" <ilyayaroshenko gmail.com> writes:
Hello!

Is there any ability to lambda function call itself?

Is it correct feature for D?

Best Regards,
Ilya
Dec 30 2013
next sibling parent reply "lomereiter" <lomereiter gmail.com> writes:
Use Y combinator?
http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-learn puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com
Dec 30 2013
parent reply "Ilya Yaroshenko" <ilyayaroshenko gmail.com> writes:
On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:
 Use Y combinator?
 http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-learn puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com
This is not lambda =( I want something like enum factrorial5 = (a => a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function
Dec 30 2013
next sibling parent "lomereiter" <lomereiter gmail.com> writes:
On Monday, 30 December 2013 at 21:15:43 UTC, Ilya Yaroshenko 
wrote:
 I want something like

 enum factrorial5 = (a => a == 0 ? 1 : a * __lambda(a-1))(5);
 //Recursive pure lambda function
That isn't supported in D. And cases where this would be useful are too rare to add complexity to the language. Just use a regular function, it's not much more code.
Dec 30 2013
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 10:15 PM, Ilya Yaroshenko wrote:
 On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:
 Use Y combinator?
 http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-learn puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com
This is not lambda =( I want something like enum factrorial5 = (a => a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function
enum factorial5=(function int(a)=>a==0?1:a*__traits(parent,{})(a-1))(5); (In D, you need to specify the return type for a recursive function declaration. If one doesn't here, DMD crashes, which is a bug. https://d.puremagic.com/issues/show_bug.cgi?id=11848)
Dec 30 2013
parent reply "Meta" <jared771 gmail.com> writes:
On Monday, 30 December 2013 at 21:58:29 UTC, Timon Gehr wrote:
 On 12/30/2013 10:15 PM, Ilya Yaroshenko wrote:
 On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:
 Use Y combinator?
 http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-learn puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com
This is not lambda =( I want something like enum factrorial5 = (a => a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function
enum factorial5=(function int(a)=>a==0?1:a*__traits(parent,{})(a-1))(5); (In D, you need to specify the return type for a recursive function declaration. If one doesn't here, DMD crashes, which is a bug. https://d.puremagic.com/issues/show_bug.cgi?id=11848)
And of course I'm wrong about that as soon as I post. No idea why one works when the other doesn't...
Dec 30 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 11:50 PM, Meta wrote:
 enum factorial5=(function int(a)=>a==0?1:a*__traits(parent,{})(a-1))(5);

 (In D, you need to specify the return type for a recursive function
 declaration. If one doesn't here, DMD crashes, which is a bug.
 https://d.puremagic.com/issues/show_bug.cgi?id=11848)
And of course I'm wrong about that as soon as I post. No idea why one works when the other doesn't...
AFAICT, none of the cases is supposed to work: https://d.puremagic.com/issues/show_bug.cgi?id=8307 Presumably it is the same bug that causes the segfault. The underlying cause might be a missing check for completion of return type inference. In the first case, this means that the return type of the function is null when it is encountered in the function body. When null is checked for compatibility with multiplication with an int, a null pointer dereference occurs. In the second case, the return type has been partly resolved to 'int' as the first return statement has been analyzed to completion before the function call is encountered.
Dec 30 2013
prev sibling parent "Meta" <jared771 gmail.com> writes:
On Monday, 30 December 2013 at 21:15:43 UTC, Ilya Yaroshenko 
wrote:
 On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:
 Use Y combinator?
 http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-learn puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com
This is not lambda =( I want something like enum factrorial5 = (a => a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function
You can do this with __traits(parent, {}), but it's ugly. auto fact = function(int n) { if (n == 0) { return 1; } else { enum self = __traits(parent, {}); return n * self(n - 1); } }; Unfortunately, a shorter version written with the lambda syntax doesn't work, it just segfaults: auto fact = (int n) => (n < 2) ? 1 : n * __traits(parent, {})(n - 1);
Dec 30 2013
prev sibling parent "TheFlyingFiddle" <kurtyan student.chalmers.se> writes:
On Monday, 30 December 2013 at 11:23:39 UTC, Ilya Yaroshenko 
wrote:
 Hello!

 Is there any ability to lambda function call itself?

 Is it correct feature for D?

 Best Regards,
 Ilya
Well it's possible to do this (sort of). //You could for instance define the Factorial function like this. int delegate(int) f; f = (int x) => x > 0 ? f(x - 1) * x : 1; It's not very pretty and offers little compared to just make it a normal function. void f(int x) { return x > 0 ? f(x - 1) * x : 1; }
Dec 30 2013