Re: [boost] Boost.Local Review (Nov 10, 2011 to Nov 19, 2011)

Hi Lorenzo, Now that I have better understood your library, my personal preference goes towards "closure". The reason for that is: 1. "Closure" better reflects the nature of your library: you provide a tool for defining closures: something more than functions, and something less than lambda expressions. 2. This may make the learning of the library easier. If I know I am dealing with closures I already expect binding functionality; there will be less questions like "what is this 'bind' and what does it actually do?" 3. It may be a marketing bonus "closure" sounds (IMO) more attractive than "function". How about Boost.Closure library? "Local" may not even be necessary, because "closure" somehow implies locality. (you do not need a global closure, because global function will do). Regards, &rzej

On Wed, Nov 16, 2011 at 9:34 AM, Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
Yes, I was thinking about it after you suggest it yesterday. I'd say the options become: a) Boost.Local: BOOST_LOCAL_FUNCTION[_END], BOOST_LOCAL_EXIT[_END], BOOST_LOCAL_BLOCK[_END] b2) Boost.Nested: BOOST_NESTED_FUNCTION[_END], BOOST_NESTED_SCOPE_EXIT[_END], BOOST_NESTED_BLOCK[_END] c) Boost.Scoped: BOOST_SCOPED_FUNCTION[_END], BOOST_SCOPED_EXIT[_END], BOOST_SCOPED_BLOCK[_END] e) Boost.Closure: BOOST_CLOSURE[_END], BOOST_CLOSURE_SCOPE_EXIT[_END], BOOST_CLOSURE_BLOCK[_END] I also like Boost.Closure (and related macro names). Maybe BOOST_CLOSURE_SCOPE_EXIT is the only one that sounds a bit strange but I still think it does not sound bad. I'd like to hear opinions from other Boosters :) Thanks for the idea! --Lorenzo

On Wed, Nov 16, 2011 at 10:24 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
After studying in details a few references: http://en.wikipedia.org/wiki/Closure_(computer_science) http://en.wikipedia.org/wiki/Anonymous_function http://en.wikipedia.org/wiki/Funarg_problem N2550, N3242 I concluded that, if there are no objects, I would like to rename my library Boost.Closure as suggested by Andrzej: Boost.Closure BOOST_CLOSURE, BOOST_CLOSURE_END (for local functions with their bound variables) BOOST_CLOSURE_SCOPE_EXIT, BOOST_CLOSURE_SCOPE_EXIT_END BOOST_CLOSURE_BLOCK, BOOST_CLOSURE_BLOCK_END The reason is because the definition of closure is (from Wikipedia): "In computer science, a closure (also lexical closure, function closure or function value) is a function together with a referencing environment for the non-local variables of that function. A closure allows a function to access variables outside its typical scope". Such a definition matches precisely what my library does. I also realized that I need to fix a bug when the closure is returned outside its local scope where it is defined. Again from Wikipedia: "A language implementation cannot easily support full closures if its run-time memory model allocates all local variables on a linear stack. In such languages, a function's local variables are deallocated when the function returns. However, a closure requires that the free variables it references survive the enclosing function's execution. Therefore, those variables must be allocated so that they persist until no longer needed. This explains why, typically, languages that natively support closures also use garbage collection. The alternative is for the language to accept that certain use cases will lead to undefined behaviour, as in the proposal for lambda expressions in C++." When the closure is returned outside its definition scope, if a variable is bound by reference, the behaviour is correctly undefined because the referenced variable does not exist anymoore. However, if the variable is bound by value, the closure should work even outside its local scope of definition instead currently my library produces an undefined behaviour also with value bindings so I have to fix that. For example: boost::function<void ()> counter() { int x = 0; int delta = 2; void BOOST_CLOSURE(bind& x, bind delta) { x += delta; std::cout << "x = " << x << std::endl; } BOOST_CLOSURE_END(increment) increment(); // ok return increment; } int main() { boost::function<void ()> inc = counter(); inc(); // (1) error (undefined behaviour) return 0; } (1) correctly doesn't work because x is bound by reference (and x no longer exists after counter() returns). However, if x was not bound by reference (e.g., make it a function parameter) then (1) should work (but currently it doesn't in my library implementation so I have to fix that): boost::function<void (int&)> counter() { int delta = 2; void BOOST_CLOSURE(int& x, bind delta) { x += delta; std::cout << "x = " << x << std::endl; } BOOST_CLOSURE_END(increment) return increment; } int main() { int x = 1; boost::function<void (int&)> inc = counter(); inc(x); // undefined behaviour now but it should work... return 0; } AFAIU, C++11 lambdas work the same way (I also run a few C++11 lambda examples to verify that): If you bind by reference then you can only use the lambda within the scope in which the reference is valid but if you bind by value you don't have that constraint. Thanks. --Lorenzo

On Fri, Nov 18, 2011 at 1:44 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Wed, Nov 16, 2011 at 10:24 AM, Lorenzo Caminiti
[...]
Of course, you meant "bind x" or "int x" here instead of "int& x", right?
[...] - Jeff

On Fri, Nov 18, 2011 at 1:31 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
No, I meant int& x. In this case the local function accepts one parameter of type int& and it is closed over a copy of value of the local variable delta. Given that none of the variables is bound by reference (the only reference is a function parameter and not a bound variable), such a closure can be safely returned to another scope and executed outside the local scope (within main in this case). When main will execute the closure, it will have to pass the one parameter x (see inc(x) below).
Thanks. --Lorenzo

On Fri, Nov 18, 2011 at 3:20 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Ack, right. I wasn't paying attention and didn't notice that you had moved the x variable to main relative to the preceding (snipped) example. - Jeff

On Fri, Nov 18, 2011 at 4:44 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
If local exits are removed (because void and this_ binding (but not const bindings) are added to Boost.ScopeExit) and localblocks are removed (because not everyone sees them as useful and because they can be trivially implemented using a local function that is called right after being defined), then Boost.Local can be renamed simply to Boost.LocalFunction (as suggested in some other thread). That would make sense to me. --Lorenzo
participants (3)
-
Andrzej Krzemienski
-
Jeffrey Lee Hellrung, Jr.
-
Lorenzo Caminiti