Friday, May 21, 2010

Use lambda caculus to analyze the C++ template

I am looking at some template expandsion for boost c++ _1 in the conext of:
foreach(vector, cout<<_1;)
The statment is expanded to a template:
boost::lambda::lambda_functor<
     boost::lambda::lambda_functor_base<
           boost::lambda::bitwise_action<boost::lambda::leftshift_action>,
           boost::tuples::tuple<
                       boost::lambda::lambda_functor<
                               boost::lambda::lambda_functor_base<
                                     boost::lambda::bitwise_action<boost::lambda::leftshift_action>
                                     boost::tuples::tuple<
                                           std::ostream&,boost::lambda::lambda_functor<
                                                   boost::lambda::placeholder<1>
                                           >,
                                           boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type
                                     >
                               >
                      >,
                      const char,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type
         >
   >
>::operator ()




It is very tedious to analyze it. The idea is to use lambda calculus to help:
  • Extended Rules for better reading
    • One large character to represent function
    • three small characters to represent variable name
    • the , [ { may be used to distinguish multiple parameters
  • Function and variables definition
    •  F.arg      the lambda functor
    • B.ret,arg   the lambda base functor which takes return value and argument
    • A.act     The bitwise action, which helps to select left,right type as return type
    • T.t0,t1..t9     The tuple can take up to 10 different types
    • lsa     left shift action
    • ofs    ofstream
    • pl1     place holder one
    • nut    null type
  • The whole template can be defined as:
  lambda.F(B(A{TF[B(A(lsa),T(ofs,F(pl1)))]}))
  •  Parse this function:
    • T(ofs,F(pl1))  associate the ofstream and _1
    • B(A(lsa), T(ofs,F(pl1))) Add the return value of the ofstream to the base functor
    • TF[...] wrap it as an function and put it in a tuple 
    • F(B(A{...})) Use the tuple as an action and then pass it to the Base functor and Functor.

No comments: