6

Does Boost Lambda/Phoenix supports out of box something like lambda which returns another lambda?

For instance, that can be used to do some kind of currying:

std::cout << [](int x){return [=](int y){return x+y;};}(1)(2);

How to achieve similar purpose with Boost Lambda/Phoenix (+ as a bonus - we would get polymorphic behaviour)?

Andrew Aylett
  • 39,182
  • 5
  • 68
  • 95
qble
  • 1,256
  • 2
  • 12
  • 29
  • The problem I had in trying to answer this is that `arg1` gets consumed by the outermost `bind` -- I want an `arg1` I can pass to the inner `bind`, but the outer `bind` eats it instead. If I had a way to "escape" the argument placeholder... – Yakk - Adam Nevraumont Mar 04 '13 at 20:11
  • @Yakk, you could try to use boost::bind - AFAIK it differs from lambda/phoenix bind ( http://www.boost.org/doc/libs/1_53_0/doc/html/lambda/s08.html#idp111396608 ). Also, post code of your try as answer - bounty ends tomorrow... – qble Mar 05 '13 at 11:00

1 Answers1

5

Boost Phoenix Scope: let/lambda

Live demo:

#include <boost/phoenix.hpp>
#include <iostream>
#include <ostream>

using namespace std;
using namespace boost;
using namespace phoenix;
using namespace arg_names;
using namespace local_names;

int main()
{
   // capture by reference:
   cout <<
      (lambda(_a=_1)[_1 + _a ])(1)(2)
   << endl;
   cout <<
      (lambda(_b=_1)[lambda(_a=_1)[_1 + _a + _b ]])(1)(2)(3)
   << endl;
   // capture by value:
   cout <<
      (lambda(_a=val(_1))[_1 + _a ])(1)(2)
   << endl;
   cout <<
      (lambda(_b=val(_1))[lambda(_a=val(_1))[_1 + _a + _b ]])(1)(2)(3)
   << endl;
}

Output is:

3
6
3
6
Evgeny Panasyuk
  • 9,076
  • 1
  • 33
  • 54
  • @EvgenyPanasyuk is there an easy way to generate a lazy evaluation, like `[&]()->void{ fully_bound_expression_that_does_not_run_until_later; }`? – Yakk - Adam Nevraumont Mar 09 '13 at 14:11
  • @Yakk, Could you please describe in details what do you mean (maybe via full example with C++11 lambdas)? Do you mean http://liveworkspace.org/code/30jCv6$0 ? Or maybe http://liveworkspace.org/code/2Kon3g$0 ? – Evgeny Panasyuk Mar 09 '13 at 16:34
  • `void some_function(int x); auto lazy_do_on_x = [](int x){return [=]{some_function(x);};}; auto lazy_do = lazy_do_on_x(5); lazy_do();` -- when I naively try to use `bind`, when every argument is bound, it evaluates the expression. Instead, I want to `bind` lazily, so the final execution only happens after I evaluate (using `()`) the nullary result of the `bind`. – Yakk - Adam Nevraumont Mar 09 '13 at 18:14
  • @Yakk, std::bind does return nullary function: auto lazy=bind(some_function,11); lazy(); http://liveworkspace.org/code/2BLbzn$0 – Evgeny Panasyuk Mar 09 '13 at 19:53