Boost logo

Boost :

Subject: Re: [boost] [local] Review
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-21 06:41:27


On Sun, Nov 20, 2011 at 11:16 PM, Thomas Heller
<thom.heller_at_[hidden]> wrote:
> On 11/20/2011 09:27 PM, Gregory Crosswhite wrote:
>>
>> On Nov 21, 2011, at 11:36 AM, Thomas Heller wrote:
>>
>>> I vote to not include Boost.Local into Boost for the following reason.
>>> I obviously can not appreciate the value of local functions in C++.
>>
>> I similarly have trouble seeing the value of the higher-order functional
>> programming constructs provided by Phoenix.  Personally when I want to
>> program in a functional programming style I write my code in a language
>> Haskell rather than shoehorning functional programming into C++ constructs
>> that were never designed for such a purpose.  When I translate my Haskell
>> code into C++ (as I have done for a numerical code I once wrote), I would
>> never think of using Phoenix, but instead I would change the idioms that I
>> was using to match C++'s stateful, imperative nature.
>
> You should definitely take a look at spirit. Try to use Local in semantic
> actions.

OK but I'm not at all a Spirit or Phoenix expert so I'll really need
your help and guidance. Please note that I'm no Phoenix expert and I
know almost nothing about Spirit so this is not aimed to show that
Boost.Local could be useful in this context (I have literally no way
to predict or assess such usefulness upfront given my sever lack of
expertise with Spirit). I'm honestly intellectually interested in
discovering the outcome of this exercise together :)

Let me start by using Boost.Local to program the semantic action's
example from the Spirit docs:
http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/qi/actions.cpp

#include <boost/local/function.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>

namespace client {

namespace qi = boost::spirit::qi;

struct print_action {
    void operator()(int const& i, qi::unused_type, qi::unused_type) const {
        std::cout << i << std::endl;
    }
};

} // namespace

int main() {
    using boost::spirit::qi::int_;
    using boost::spirit::qi::parse;
    using boost::spirit::qi::unused_type;
    using client::print_action;

    { // example using simple function object

        char const *first = "{43}", *last = first + std::strlen(first);
        parse(first, last, '{' >> int_[print_action()] >> '}');
    }

    { // example using Boost.Local
        void BOOST_LOCAL_FUNCTION_PARAMS(int const& i,
                unused_type, unused_type) {
            std::cout << i << std::endl;
        } BOOST_LOCAL_FUNCTION_NAME(print_local)

        char const *first = "{40}", *last = first + std::strlen(first);
        parse(first, last, '{' >> int_[print_local] >> '}');
    }

    return 0;
}

This compiles and runs (I can say that much :) ) but a part from that
I can't quite comment given my Spirit ignorance. I honestly ask you:
What do you think?

Notes:
1) Is this too easy of an example? If so, where can I find a more
complex one? Maybe in other points of the docs?
2) I removed the Bind, Lambda, and global function versions
thinking/assuming that the comparison with global functor was the most
interesting one... was that a mistake?

Thanks.
--Lorenzo


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