[local] local functions ready for review

Hello all, A few months ago, I probed for interest in a library for local functions with Boost.ScopeExit's variable binding. Based on that discussion, I have now implemented the Boost.Local library. I have uploaded the source files boost-local_0_1_0-818.zip in the Boost Vault under Function Objects: http://www.boostpro.com/vault/index.php?&direction=0&order=&directory=Function%20Objects The documentation on the web: http://contractpp.sourceforge.net/boost-local_0_1_0-818/libs/local/doc/html/... Any comment? As far as I can tell, Boost.Local is ready for a formal review so I am looking for a review manager. Any volunteer? Thanks, Lorenzo ________________________________________________ P.S. A preview from Boost.Local's documentation: The Boost Local library implements local functions, local blocks, and local exits for the C++ programming language. INTRODUCTION Local functions are a form of information hiding and are useful for dividing procedural tasks into subtasks which are only meaningful locally, avoiding cluttering other parts of the program with functions, variables, etc unrelated to those parts. Local functions therefore complement other structuring possibilities such as namespaces and classes. Local functions are a feature of many programming languages, notably Pascal and Ada, yet lacking from C++ (see also [N2511]). This library supports the following features for local functions (see the Alternatives section for a comparison between this library and features offered by C++ local class members, C++0x lambda functions, Boost.Lambda, Boost.Phoenix, and Boost.ScopeExit): * Local functions can access, or better bind, any of the variables from the enclosing scope. Furthermore, local functions defined within a member function can bind the enclosing object this. * The local function body is programmed using the usual C++ syntax. * Local functions can be passed as template parameters (so they can be conveniently passed to STL algorithms, etc). * However, local functions must be defined within a declarative context (e.g., at a point in the code where local variables can be declared) thus they cannot be defined within an expression. In addition to local functions, this library also supports the following features: * Local blocks which define blocks of code that bind variables from the enclosing scope. Local blocks allow programmers to bind variables as constants (constant binding) so to prevent local chunks of code from modifying selected variables. * Local exits which define blocks of code that are executed when the enclosing scope is exited (again with support for constant binding and binding of the object this). AN EXAMPLE The following example illustrates a simple use of this library and it starts introducing the library API (see the Tutorial section for more details on how to use this library): * A local function is passed to the STL std::for_each() algorithm to add together the values of an array. Variables in scope are bound to the local function by both constant value and non-constant reference. * A local exit is used to automatically release the array's memory at scope exit. * A local block is used to assert the correct final value of the summation in a constant-correct context (therefore preventing the assertion from mistakenly changing any of the variables in scope). #include <boost/local/function.hpp> #include <boost/local/block.hpp> #include <boost/local/exit.hpp> #include <algorithm> #include <iostream> #include <cassert> int main() { double sum = 0.0; int factor = 10; 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); size_t size = 2; double* nums = new double[size]; BOOST_LOCAL_EXIT( (const bind)((&size)) (bind)((nums)) ) { if (size && nums) delete[] nums; std::clog << "Freed array: " << nums << std::endl; } BOOST_LOCAL_EXIT_END nums[0] = 90.5; nums[1] = 7.0; std::for_each(nums, nums + size, add); BOOST_LOCAL_BLOCK( (const bind)((&sum)) ) { // So far: sum = 10 * 100.0 + 10 * 90.5 + 10 * 7.0 = 1975.0 assert(sum == 1975.0); std::clog << "Asserted summation: " << sum << std::endl; } BOOST_LOCAL_BLOCK_END return 0; }

On 1/3/2011 12:22 PM, Lorenzo Caminiti wrote:
I can understand the potential usefulness of local functions and local exits, but it seems local blocks serve little purpose, other than an easier syntactical notice, because it is a macro, over a simple block using { } which can also of course access variables in the enclosing scope. I do see where one can bind variables in local blocks in a few ways but that seems to offer little over just normal C++ blocks. Nonetheless your library seems interesting. Would you consider putting it in the sandbox also ( or instead ) ? That way, when and if you need to update it, others can pick up the updates via SVN.
As far as I can tell, Boost.Local is ready for a formal review so I am looking for a review manager. Any volunteer?
I can understand your being eager for a review, but shouldn't you let interested parties use it first for a short period of time ?

On Mon, Jan 3, 2011 at 12:58 PM, Edward Diener <eldiener@tropicsoft.com> wrote:
It's funny that local blocks were actually the main use case that motivated me in developing the library... My use case for local blocks was to check assertion in a constant-correct context (this is also explained in the Boost.Local documentation). Consider the following: void zero(int& x) { x = 0; assert(x == 0); } If I mistake operator== with operator= I will get a run-time error as the assertion will fail. However, ideally such a mistake would be caught at compile-time if I could also program the semantic constraint that assertions should not change the state of the program (but only check the state of the program). So I would like to use a "const-block" (borrowing the syntax from http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1613.pdf bottom of page 15): void zero(int& x) { x = 0; const { assert(x == 0); } } Unfortunately, this is not valid C++ syntax :( but Boost.Local const-binding can be used instead: void zero(int& x) { x = 0; BOOST_LOCAL_BLOCK( (const bind)((&x)) ) { assert(x == 0); } BOOST_LOCAL_BLOCK_END } Now if I mistake operator== with operator= I get a compile-time error :) This was the original use case that motivated me in developing Boost.Local and I still think this is a good use case that shows how local blocks can be useful. However, I agree that local functions are by far the main feature of this library. (In fact, both local exits and blocks essentially comes for free as they are implemented as local functions with no parameter and not result type.)
Yes, I am happy to upload the library in SVN. How do I do this? (I do not have write access to Boost SVN...)
Of course: Boosters please play with Boost.Local and let me know what you think! The source is in the Boost Vault and there are quite a few examples with the source plus a few more within the documentation text. I much rather have the opportunity to improve the library before a review than having the library fail the review miserably :) Thanks, -- Lorenzo

On 1/3/2011 10:04 PM, Lorenzo Caminiti wrote:
There is nothing wrong with formalizing access to variables within blocks, which is what your local blocks appear to do. I think though that most programmers may find it unnecessary. OTOH your local functions and your extension of scope exit is more useful.
I think you just have to ask for write access to the sandbox in a message on this NG. I recall that is what I did. The advantage of a sandbox library is that you create the structure of your library in such a way that it becomes much easier both to update it and for others to pick up the updates.

On Mon, Jan 3, 2011 at 12:58 PM, Edward Diener <eldiener@tropicsoft.com> wrote:
Hi all, I have uploaded Boost.Local into the Boost SVN sandbox: https://svn.boost.org/svn/boost/sandbox/local/ Let me know what you think. Thanks. -- Lorenzo
participants (2)
-
Edward Diener
-
Lorenzo Caminiti