Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2004-02-16 10:19:23


On Mon, Feb 16, 2004 at 09:19:07PM +0900, Darren Cook wrote:
> Hi,
> I've read the lambda sections of the FC++ docs, and the paper on the
> subject, and am a bit confused how to use it. Could you show the FC++
> equivalents of these BLL examples:

Sure.

I'm including just bits of commentary and code snippets in reply to
each example, and then I have also attached a full program which
demonstrates all this.

> 1. (from the paper)
> int a[]={5,3,8,4};
> std::for_each(a,a+4,std::cout<<_1<<"\n");

In FC++ it'd look like this:

   std::for_each(a,a+4,
      lambda(X)[ &cout %out_stream% X %out_stream% '\n' ] );

"out_stream" is the FC++ named functoid which refers to the << operator.
Unlike the real operator, it takes a stream _pointer_ as the left-hand
argument (because FC++ uses value semantics, and thus references are
icky).

The %s are FC++'s lambda infix syntax; recall that for any FC++ functoid
f, you can say

   f(x,y) or x ^f^ y

to call f "now" with args x and y, or you can say

   f[x,y] or x %f% y

to do the same thing inside lambda to delay evaluation and turn the call
into a lambda expression.

> 2.
> int a[]={5,3,8,4};
> std::for_each(a,a+4,std::cout<<constant("v=")<<_1<<"\n");

   std::for_each(a,a+4,
      lambda(X)[ &cout %out_stream% string("v=")
                       %out_stream% X %out_stream% '\n' ] );

Same thing here, with the added annoyance that you have to manually turn
the string literal into some "by-value" type (rather than the "array of
char const" type the darn templates deduce--ugh). The %s (rather than ^s)
ensure that evaluation happens "later", serving the same purpose as
boost::lambda's constant().

> 3. (a vector of MyClass pointers)
> std::for_each(
> tests.begin(),
> tests.end(),
> bind(&MyClass::save,_1,f)
> );

Here you would probably do

   std::for_each( tests.begin(), tests.end(),
      ptr_to_fun(&MyClass::save)(_,5) );

assuming that "save" is a normal method. ptr_to_fun() converts a C++
function pointer into an FC++ functoid (with an extra "this" parameter
for member functions). Here we use the short for for partial
application:

   f(_,5)

which means the same as

   lambda(X)[ f[X,5] ]

Note that if "save" were defined by MyClass as a functoid, things get
even easier in the client code; see the attached example (and YourClass)
for details.

> 4.
> std::for_each(
> tests.begin(),
> tests.end(),
> bind(delete_ptr(), _1)
> );

In FC++ we have a functoid called "delete_":

   std::for_each( tests.begin(), tests.end(), delete_ );

> 5. (in a spirit parser)
> Node= +(
> (+range_p('A','Z'))[bind(&MyClass::on_name, this, _1,_2)]
> >> +(
> ch_p('[')
> >> (*(anychar_p-']'))[bind(&MyClass::on_value, this, _1,_2)]
> >> ch_p(']')
> )
> );

I didn't do these examples (seemed to require too much extra context),
but the gist of it would again be that

   bind(&MyClass::on_name, this, _1,_2)

would be spelled

   ptr_to_fun(&MyClass::on_name)(this)
   // or, equivalently
   // ptr_to_fun(&MyClass::on_name)(this,_,_)

in FC++ if "on_name" is a plain method, or

   MyClass::on_name(this)

if it were a functoid.

See the attached program for more detail if you like, and please ask
more questions if you have them.

Brian

-- 
-Brian McNamara (lorgon_at_[hidden])



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk