Subject: Re: phoenix lambda-lambda for_each example
From: Aleksey Gurtovoy <[email-masked]>
To: David Abrahams <[email-masked]>
Cc: Jaakko Jarvi <[email-masked]>, Joel de Guzman <[email-masked]>, Noah Stein <[email-masked]>
Date: Thu, 04 Mar 2004 09:04:04 -0600

David Abrahams writes:
> I still don't see why compile-time has to be different from runtime in
> this regard.  The fold algorithm calls lambda<> on its 3rd argument;
> that should be enough to indicate where the scope resides.

The point is that run-time 'fold' call is basically two-phase --
during the first phase the arguments, including lambda expressions,
are passed through, composing a function object; then you invoke
the function object and the "real" call happens. 

At compile time, everything is different. When you pass a lambda
expression to 'apply', nothing gets evaluated at the point of the
lambda expression definition:

     typedef fold< _1, int_<0> 
         , fold< _2, _1, plus<_1,_2> > 
        > f; // nothing here

     typedef apply< f, vector< vector_c<int,0,1,2> > >::type r;

Instead, 'apply' has to "parse" the whole thing from outside, and
without some additional metadata about metafunctions involved, it has
no chances of figuring out implicit scopes. Compare that to the
following run-time equivalent, keeping in mind the first paragraph,
and you'll see the difference:

     template< typename F, typename T >
     void apply( F f, T x )
     {
        f(x);
     }

     apply( 
          fold(_1, 0, fold(_2, _1, _1 + _2)) // 'fold's get evaluated,
                                             // taking care of scope parsing
        , std::vector< std::vector<int> >()
        );

-- 
Aleksey Gurtovoy
MetaCommunications Engineering