
On 11/24/2011 8:06 AM, Brent Spillner wrote:
On 23 Nov 2011 10:21:50 Joel de Guzman wrote:
a good approximation of lambda is already existing in Boost. Namely: bind, lambda and phoenix. I posted a Spirit example of lambda in action using Phoenix:
Try as hard as you can, but you cannot ever come close to the clarity of he syntax presented there. Proponents of locals have cited error-messages generated by the compiler as a justification for Locals. Locals is probably a good workaround. But hear me out...
First of all, this "trivial" example didn't even compile on the first machine I tried it on, which had Boost 1.45 (which doesn't expose qi:_val_type or qi:_1_type). This is a pretty good reminder of the
Man! Of course you should use the examples in 1.45. Those examples are for 1.48 and uses new features implemented in 1.48! Sheesh!
On a machine with 1.48, the example compiles just fine. If you were to pass std::string::iterators instead of const_iterators to phrase_parse(), though ( a pretty common class of mistake in the real world), you get this error message (GCC 4.4.4):
Double Sheesh! If you've spent even a few seconds looking into the error (beyond fault-finding), you will see that a simple textual search of "error" will reveal this:
------------------- Horrific error messages follow ---------------------
calc3.cpp:90: instantiated from here /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:176: error: no matching function for call to 'assertion_failed(mpl_::failed************ (boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [snip ... some complex types] ::error_invalid_expression::************) And double clicking on it using your editor will lead you here: static void define(rule& lhs, Expr const& expr, mpl::false_) { // Report invalid expression error as early as possible. // If you got an error_invalid_expression error message here, // then the expression (expr) is not a valid spirit qi expression. BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr); } If you've read the Spirit docs, you will know what that means. Now having said that, and before I leave this thread, let me remind everyone that **you can also have statement syntax in Phoenix** if you have a complex statement and you fear writing complex phoenix lambda expressions. It's called phoenix::functions. In fact here's what I advocate: 1) For simple 1-2-3 liners, use a phoenix lambda expression. It's hard to get them wrong. For example, you'll have to be absurdly dumb to get this wrong: auto plus = _1 + _2; 2) For more complex expressions, especially those involving statements, use a phoenix function plus a simple lambda expression that forwards to the phoenix function. Example: for_each(f, l, call_complex_function(_1)); Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com