Thread overview
Recursive lambda functions?
Dec 30, 2013
Ilya Yaroshenko
Dec 30, 2013
lomereiter
Dec 30, 2013
Ilya Yaroshenko
Dec 30, 2013
lomereiter
Dec 30, 2013
Timon Gehr
Dec 30, 2013
Meta
Dec 30, 2013
Timon Gehr
Dec 30, 2013
Meta
Dec 30, 2013
TheFlyingFiddle
December 30, 2013
Hello!

Is there any ability to lambda function call itself?

Is it correct feature for D?

Best Regards,
Ilya
December 30, 2013
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
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
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
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
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
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
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
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.