|
Boost : |
Subject: Re: [boost] Rave for proposed Boost.Local (functions)
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-02-05 12:03:40
On Wed, Feb 2, 2011 at 2:00 AM, Thomas Heller
<thom.heller_at_[hidden]> wrote:
> Gregory Crosswhite wrote:
>
>> Hey everyone,
>>
>> The purpose of this e-mail is to rave about Lorenzo's proposed
>> Boost.Local library in the hopes of inspiring people to start the review
>> process for it. :-)
>>
>> I have been experimenting with using this library in my own code, and it
>> has been a godsend for me. In one of the projects I have been working
>> on I ran into many situations where I needed to call a higher-order
>> function with a closure, and the closure was just complicated enough
>> that I couldn't use Boost.Lambda. Before using this library I
>> frequently found myself either writing a lot of extra code to
>> work-around the need for a higher-order function, or writing a lot of
>> boilerplate to create classes that would only be used by a single
>> function in order to create a function object. This library has let me
>> write the closures that I need in a fairly painless fashion and so has
>> made my life a lot easier!
>
> I would be interested in what limitations you ran into using Boost.Lambda
> and if you are aware of the recent efforts that were put into Boost.Phoenix?
>
>> To my mind this example looks a lot clearer if you reformat it as follows:
>>
>> BOOST_LOCAL_FUNCTION(
>> (void) (add)(
>> (double)(num)
>> (const bind)((factor))
>> (bind)((&sum))
>> )
>> ) {
>> sum += factor * num;
>> std::clog<< "Summed: "<< sum<< std::endl;
>> } BOOST_LOCAL_FUNCTION_END(add)
>> add(100.0);
>
> As far is a am concerned, I still find this syntax overly verbose.
> I do realize though that this is just a toy example. For better comparison,
> Here is how the same thing would like in Boost.Phoenix:
>
> boost::function<void(double)> add
> =(
> ref(sum) += factor * _1,
> std::clog << var("Summed: ") << sum << std::endl
> )
> ;
> add(100.0);
Can you make factor constant within add() body using Boost.Phoenix? If
not, then I could not use Boost.Phoenix for my original use case* that
motived Boost.Local (local constant blocks). And that's why C++0x
lambdas are also not useful for me because they do not support
constant binding -- why don't they?? :(( -- plus I use an oldish
gcc-based tool chain for an embedded system and there is no plan to
get a C++0x release for it at the moment...
(*) My original use case required (1) to write the body is normal C++
syntax (so I could not use Boost.Phoenix) and (2) to use constant
binding (I am not sure but I don't think Boost.Phoenix can do constant
binding, I know C++0x lambdas cannot) to check assertions in a
constant correct context:
void f(int& zero) {
BLOCK_INVARIANT( (const (zero) (zero == 0)) ) // Compiler
error if programmers mistake `==` with `=`.
...
}
I can do this with Boost.Local:
void f(int& zero) {
BOOST_LOCAL_BLOCK( (const bind)(&zero) ) {
assert(zero == 0);
} BOOST_LOCAL_BLOCK_END
}
How can I do this in Boost.Phoenix? How can I do this in C++0x
lambdas? (Note requirements (1) and (2).)
Maybe this use case is not very interesting to other people but it was
important for me.
> Despite the Local Blocks and Local Exits feature, I can't see much
> difference to the already existing lambda libraries.
> I just looked through the Boost.Local documentation and immediately
> navigated to the "Alternatives" section and its not really correct regarding
> the features of Boost.Lambda and Boost.Phoenix. I am specifically talking
> about the "Bind variables in scope" and "Program body using usual C++
The Alternatives section is based on this previous Boost discussion
http://permalink.gmane.org/gmane.comp.lib.boost.devel/212255 .
I also think it is not a complete comparison. For example, I wanted to
add the add() example -- add add() ;) -- reworked in Boost.Phoenix,
Boost.Lambda, C++0x lambdas, and C++ local classes but I didn't have
time yet... Thanks a lot of the above code in Boost.Phoenix, I'll add
it to Boost.Local doc :)
> syntax" part. The last is debatable, but how are the above examples (both of
> Boost.Local and Boost.Phoenix) not C++ syntax?
> Can you highlight the advantages/disadvantages again?
Yes, this is debatable and at the end it's of course all C++. But the
Boost.Local function body defined within `{ ... }` it's the normal C++
syntax for function definitions. For example, Boost.Phoenix uses `,`
where C++ and Boost.Local use `;` to terminate and instruction,
Boost.Phoenix uses `var("Summed:")` where C++ and Boost.Local use
`"Summed:"`, etc.
Plus, how would local variables and local classes look in
Boost.Pheenix? In Boost.Local it's like in normal C++:
BOOST_LOCAL_FUNCTION(
(void) (add)(
(double)(num)
(const bind)((factor))
(bind)((&sum))
)
) {
const std::string msg = "Summed: "; // A const local var.
struct text { std::string say; } // A local struct.
test t; // A local var.
t.say = msg;
sum += factor * num;
std::clog<< t.say << sum<< std::endl;
} BOOST_LOCAL_FUNCTION_END(add)
add(100.0);
How would this look in Boost.Phoenix? I wish I knew Phoenix better :)
so I could provide the answers myself...
-- Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk