6

Is there a way to create a typedef such that the following (a basic "pure" implementation of the y-combinator) would compile?

typedef ??? f;
[](f x){x(x);} ([](f x){x(x);});

This has the effect of creating a "recursive lambda", i.e. one which calls itself by using a second lambda to get a reference to itself. x in the first lambda is a reference to the second lambda, so x(x) calls the second lambda with a reference to itself. Thereafter, the second lambda recurses by calling x(x). This code, when executed, should produce an infinite loop until it hits stack overflow. More sophisticated implementations of the second function can produce arbitrary recursive behaviour.

I have tried typedefing various versions of void(*)(...) but I do not believe that can succeed. My template metaprogramming is not strong enough to handle this kind of thing.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • What does `x(x);` suppose to do (assuming it is possible)? Also what does the argument `([](f x){x(x);})` mean and do? Give us some idea as to what you're doing. – Nawaz Mar 11 '13 at 18:20
  • Just recurse. It's a y-combinator. – nneonneo Mar 11 '13 at 18:24
  • @nneonneo: OK, I don't know what a y-combinator is, so I guess my answer looks idiotic. Should that just set up an infinite recursion by calling itself? And are you allowed to define a new class `X`, and then `typedef X f`? – Andy Prowl Mar 11 '13 at 18:26
  • 2
    You cannot create directly-recursive types through a typedef. – Xeo Mar 11 '13 at 18:28
  • @AndyProwl: Sorry. I expanded the question to define what I am doing. And yeah, a new class is OK. – nneonneo Mar 11 '13 at 18:32
  • 1
    I think what are you asking is basically what it was done here http://codereview.stackexchange.com/questions/3111/my-implementation-of-fixed-point-combinator-in-c1x-compiled-under-vistual-stu – Pedrom Mar 11 '13 at 18:43
  • @Pedrom: Interesting. They just defined a functor `loopfunc_t` and a `std::function<...loopfunc_t>`. So that's how you can do a recursive function -- brilliant! – nneonneo Mar 11 '13 at 18:48
  • I thought the C++11 standard says that lambdas cannot be recursive. – Nils Mar 12 '13 at 11:02
  • @Nils: where does it say that? – nneonneo Mar 12 '13 at 18:19
  • I don't remember, but thought I read it somewhere. – Nils Mar 13 '13 at 08:17

1 Answers1

6

How about this one?

#include <functional>
#include <iostream>

struct X
{
    template<typename F>
    X(F f) : _f(f)
    { }

    void operator () (std::function<void(X)> f)
    {
        std::cout << "Calling myself..." << std::endl;
        _f(f);
    }

    std::function<void(X)> _f;
};

int main()
{
    typedef X f;
    [](f x){x(x);} ([](f x){x(x);});
}
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451