Boost logo

Boost :

Subject: [boost] [local] name (was Re: "protected" APIs)
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-01-16 08:55:00


On Mon, Jan 16, 2012 at 6:06 AM, Thomas Klimpel
<Thomas.Klimpel_at_[hidden]> wrote:
> Hartmut Kaiser wrote:
>> > On 01/02/2012 10:25 AM, Lorenzo Caminiti wrote:
>> > > Hello all,
>> > >
>> > > Boost.Closure (formerly, Boost.Local) needs to use some macros,
>> types,
>> > > etc that are currently marked private in Boost.ScopeExit:
>> >
>> > Boost.Closure? I really don't like that name is at implies functional
>> > programming capabilities. Didn't you decide to name it
>> Boost.LocalFunction
>> > instead?
>>
>> I second that concern. I wouldn't like for the local function library
>> to
>> claim the name 'closure'.
>> This would be
>>
>>    a) totally misleading and
>>    b) inhibits to give that name to a potential real closure library in
>> the
>> future.
>
> +1

As I said before, I'm equally happy with Boost.LocalFunction and
Boost.Closure. I'm checking with my review manager about going back
from Closure to LocalFunction given that a few people have now
expressed such a preference. I'll keep everyone posted :)

> Or more precisely, just ignoring mails questioning the name Boost.Closure is not good style. In a functional programming language, many things can be done with a closure (for example returning it from a function), and it is unclear to me, whether Boost.Local really is able to approximate this functionality in a sufficiently usable way. It might be true, but then please point me to the corresponding passage in the documentation.

Boost.Local docs do not (yet) explain how and when local functions can
be returned because that was a homework from the review. I'm pasting
below a few examples that I will include in the docs:

//[test_return_inc_cpp
#include <boost/closure.hpp>
#include <boost/function.hpp>
#define BOOST_TEST_MODULE ReturnInc
#include <boost/test/unit_test.hpp>

boost::function<int (void)> inc(int& value) {
    int BOOST_CLOSURE(bind& value) {
        return ++value;
    } BOOST_CLOSURE_END(i)
    return i;
}

BOOST_AUTO_TEST_CASE( return_inc ) {
    int value1 = 0; // Reference valid in scope where closure is used.
    boost::function<int (void)> inc1 = inc(value1);
    int value2 = 0;
    boost::function<int (void)> inc2 = inc(value2);

    BOOST_CHECK( inc1() == 1 );
    BOOST_CHECK( inc1() == 2 );
    BOOST_CHECK( inc2() == 1 );
    BOOST_CHECK( inc1() == 3 );
}
//]

//[test_return_setget_cpp
#include <boost/closure.hpp>
#include <boost/function.hpp>
#define BOOST_TEST_MODULE ReturnSetGet
#include <boost/test/unit_test.hpp>
#include <string>

boost::function<void (std::string const&)> set;
boost::function<std::string const& (void)> get;

void action(void) {
    // State `message` hidden behind access functions from here.
    BOOST_CHECK( get() == "abc" );
    set("xyz");
    BOOST_CHECK( get() == "xyz" );
}

BOOST_AUTO_TEST_CASE( return_setget ) {
    std::string message = "abc"; // Reference valid where closure used.

    void BOOST_CLOSURE(bind& message, std::string const& text) {
        message = text;
    } BOOST_CLOSURE_END(s)
    set = s;

    std::string const& BOOST_CLOSURE(const bind& message) {
        return message;
    } BOOST_CLOSURE_END(g)
    get = g;

    action();
}
//]

//[test_return_derivative_cpp
#include <boost/closure.hpp>
#include <boost/function.hpp>
#define BOOST_TEST_MODULE ReturnDerivative
#include <boost/test/unit_test.hpp>

boost::function<int (int)> derivative(boost::function<int (int)>& f, int dx) {
    int BOOST_CLOSURE(bind& f, const bind dx, int x) {
        return (f(x + dx) - f(x)) / dx;
    } BOOST_CLOSURE_END(deriv)
    return deriv;
}

BOOST_AUTO_TEST_CASE( return_derivative ) {
    int BOOST_CLOSURE(int x) {
        return x + 4;
    } BOOST_CLOSURE_END(add2)
    boost::function<int (int)> a2 = add2; // Reference valid where closure used.

    boost::function<int (int)> d2 = derivative(a2, 2);
    BOOST_CHECK( d2(6) == 1 );
}
//]

//[test_return_this_cpp
#include <boost/closure.hpp>
#include <boost/function.hpp>
#define BOOST_TEST_MODULE ReturnThis
#include <boost/test/unit_test.hpp>

struct number {
    number(int value) : value_(value) {}

    boost::function<int (void)> inc(void) {
        int BOOST_CLOSURE(bind this_) {
            return ++this_->value_;
        } BOOST_CLOSURE_END(i)
        return i;
    }

private:
    int value_;
};

BOOST_AUTO_TEST_CASE( return_this ) {
    number n1 = 0; // Object valid in scope where closure is used.
    boost::function<int (void)> inc1 = n1.inc();
    number n2 = 0;
    boost::function<int (void)> inc2 = n2.inc();

    BOOST_CHECK( inc1() == 1 );
    BOOST_CHECK( inc1() == 2 );
    BOOST_CHECK( inc2() == 1 );
    BOOST_CHECK( inc1() == 3 );
}
//]

Thanks.
--Lorenzo


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