Adding library support for recursive lambdas

167 views
Skip to first unread message

yegor.de...@gmail.com

unread,
Sep 30, 2015, 2:05:26 PM9/30/15
to ISO C++ Standard - Future Proposals
Hi,

it looks like C++14 generic lambdas and Y combinator play really well together
when you want to write a recursive lambda. So, I wrote a draft proposal to
include Y combinator into the standard:

    http://derevenets.com/public/yc-proposal.html

Could you have a look and evaluate the idea?

--
Yegor Derevenets

Richard Smith

unread,
Sep 30, 2015, 2:26:40 PM9/30/15
to std-pr...@isocpp.org
I think this would be better as a first-class language feature. I ran out of time for the pre-Kona meeting, but I was intending on writing a paper to allow giving a lambda a name (scoped to its own body):

  auto x = []fib(int a) { return a > 1 ? fib(a - 1) + fib(a - 2) : a; };

Here, 'fib' is the equivalent of the lambda's *this (with some annoying special rules to allow this to work despite the lambda's closure type being incomplete).

Nicol Bolas

unread,
Sep 30, 2015, 2:35:38 PM9/30/15
to ISO C++ Standard - Future Proposals, yegor.de...@gmail.com
In the Design Decisions section, it claims that `y_wrapper` would have the ability to store a value or reference, depending on a template parameter. By default it stores a value, but if you construct one yourself, it can store a reference.

That doesn't seem feasible, not in the intended use case. Remember that lambda functions have a name, but they are untypeable. Calling `std::y` (a terrible function name, BTW) uses template argument deduction to figure out what the lambda's type is. But there's no such thing as template argument deduction when instantiating a template class like `y_wrapper`. So... how do you do this:

auto fib = y_wrapper<???, use_reference>([]...);

What goes in the ??? part?

Yegor Derevenets

unread,
Sep 30, 2015, 2:56:37 PM9/30/15
to Nicol Bolas, ISO C++ Standard - Future Proposals
On Wed, Sep 30, 2015 at 11:35:37AM -0700, Nicol Bolas wrote:
> By default it stores a value, but if you construct one yourself, it can
> store a reference.
>
> That doesn't seem feasible, not in the intended use case.

I meant something like this:

auto almost_fib = [](auto fib, int x) -> int {
return x <= 1 ? x : fib(x - 1) + fib(x - 2);
};

auto fib = std::y_wrapper<decltype(almost_fib) &>(almost_fib);
std::cout << fib(42) << std::endl;

Perhaps, I should add this example to the paper.

Naming is not an important issue for now. std::y is good enough for the
start, we can always pick a better name later, once we agree we need
this function in the library.

--
Yegor Derevenets
Reply all
Reply to author
Forward
0 new messages