
On Mon, Sep 13, 2010 at 5:33 PM, Pierre Morcello <pmorcell-cppfrance@yahoo.fr> wrote:
<lorcaminiti@gmail.com> wrote:
Hello all,
Local functions are essentially implemented as member functions of local classes. These member functions do not have to be static and they could be virtual allowing for a local function to override one another.
However, I cannot understand if this overriding "feature" has any value at all... Have you ever used anything similar? Can you think of a use case for it?
I can't think of any.
this or this_ ?
I personnaly prefer this_ since it is a minor problem, and seems safer.
bound or bind?
I am ok with bound, or bind as long as there is no compatibility problems with boost::bind. It would be necessary to explain in the documentation that it is not the 'bind' of boost bind. 'closure' feels a bit long, while 'ref' would even sound better to my humble ears... but this is nothing fundamental to me neither.
Using `(bind)` has not issues with respect to `boost::bind`. That is because `(bind)` (or any other pp-keyword we end up selecting) has a meaning only for the preprocessor when the macro is expanded (so there is absolutely not relationship with `boost::bind`).
Lorenzo wrote : This functionality plus the one of Boost.Breakable-like breakability would be provided by Boost.Block in terms of both const and non-const blocks. I implemented Boost.Block using Boost.LocalFunction. Note that from within a Boost.Block, return jumps to the end of the block (and it does not exit the enclosing function) therefore also proving the Boost.Breakable functionality discussed in http://archives.free.net.ph/message/20090906.123719.b890ff7a.el.html. However, I am not sure if this "block breakability" via return is a feature or a limitation because users could expect `return;` to quit exit the enclosing function as usual and not just the local void-function used to implement the Boost.Block
I am myself not convinced by your propositions on this point. If you present it like a 'block', when it's a local fuction directly called, then its more confusing than necessary.
Concerning boost.breakable it was a very simple one liner, which happens to be useful in some cases.
Concerning my earlier suggestion to add to your library was simply a local function called in-place (so presented as a local function). Of course, if you name it 'block' it is confusing. But if you use the term 'function' then it is ok for everyone to use 'return' and have a much easier interface.
instead of :
CONTRACT_DETAIL_BLOCK( (this)(x) ) { if (x <= 0) CONTRACT_DETAIL_BLOCK_BREAK; // `return` jumps to block's end. this_->x_ = x; // OK, `f` (so `this`) is non-const member function. } CONTRACT_DETAIL_BLOCK_END
using something like :
UNNAMED_FUNCTION( (this)(x) ) { if (x <= 0) return; this_->x_ = x; // OK, `f` (so `this`) is non-const member function. } UNNAMED_FUNCTION_END
would be clearer in my humble opinion. You could replace UNNAMED_FUNCTION by DIRECT_FUNCTION or something else which clearly shows that it is a function. By the way, this was the interface used by the implementation I send you at the beginning (NESTED_FUNCTION + return) .
I agree, if the macro is named `..._FUNCTION` then `return` is not confusing. What is the use case for unnamed local functions? Is it just the breakable feature? Note that unnamed lambda are more useful because they can be defined at expression level. If an expression needs a functor, like `std::for_each()` call, then you defined it using lambda right where the functor is expected so you do not even need to name the lambda function -- but that use case does not apply to local functions that cannot be defined at the expression level. In order to use local function you have to name them and call them or pass them as functors to some other function... All in all, you can always just define a named local function and call if right away with one extra line of code: BOOST_LOCAL_FUNCTION( (void) (unamed)( (bound)((this)(&x)) ) ) { if (x <= 0) return; this_->x_ = x; } BOOST_LOCAL_FUNCTION_END(unamed) unamed(); I am not sure of the utility of unnamed local functions but if there is a clear use case for them, they would be really trivial to implement. I think what we need to find is a good use case for this. I was thinking to provide `BOOST_BLOCK` for "symmetry" because I will provide `BOOST_BLOCK_CONST` (as I said the use case for const-block is to add the semantic information about const-correctness of the enclosed instructions). I'll think about this more a propose something if I can find a use case then reviewers of the library can propose alternatives -- this stuff it's really trivial to implement around the basic `BOOST_LOCAL_FUNCTION` macros.
Concerning the 'default' values that you proposed, it is an interesting idea, though I am not sure I would have a use for it.
-- Lorenzo