Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
December 30, 2013 Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Hello! Is there any ability to lambda function call itself? Is it correct feature for D? Best Regards, Ilya |
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Yaroshenko | Use Y combinator? http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-learn@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com |
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Yaroshenko | 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; }
|
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to lomereiter | 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
|
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Yaroshenko | 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.
|
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Yaroshenko | 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) |
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Yaroshenko | 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);
|
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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...
|
December 30, 2013 Re: Recursive lambda functions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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. |
Copyright © 1999-2021 by the D Language Foundation