Re: [proto] proto-11 progress report
On 06/24/2012 01:10 AM, Eric Niebler wrote: I've made some good progress on the C++11 proto rewrite that I'd like to share. So far, it's been a less radical shift than I expected. You didn't try hard enough ;) Expressions vs. Grammars Many new users are confused by the difference between terminalint and terminalint::type. In proto.next, there is no difference. Forget the ::type. Things just work. Neat Custom transforms are simpler = Currently, defining a custom transform means defining a struct with a nested impl class template of 3 parameters, correctly inheriting and following a protocol. In the rewrite, I wanted to simplify things. Here for instance, is how the _expr transform is defined: struct _expr : transform_expr { templatetypename E, typename ...Rest auto operator()(E e, Rest ...) const BOOST_PROTO_AUTO_RETURN( static_castE (e) ) }; A custom transform is simply a struct that inherits from proto::transform and that has an operator() that accepts an arbitrary number of parameters. (The use of BOOST_PROTO_AUTO_RETURN is not necessary. It simply handles the return statement, the return type, and the noexcept clause.) Good Data parameter uses a slot mechanism In proto today, transforms take 3 parameters: expression, state and data. As you can see from above, transforms in proto-11 take an arbitrary number of parameters. However, that can make it hard to find the piece of data you're looking for. Which position will it be in? Instead, by convention most transforms will still only deal with the usual 3 parameters. However, the data parameter is like a fusion::map: it will have slots that you can access in O(1) by tag. Here is how a proto algorithm will be invoked: int i = LambdaEval()(_1 + 42, 0, proto::tag::data = 8); The 3rd parameter associates the value 8 with the data tag. The _data transform returns the data associated with that tag. Additionally, you can define you own tags and pass along another blob of data, as follows: int i = LambdaEval()(_1 + 42, 0, (proto::tag::data = 8, mytag = 42)); The _data transform will still just return 8, but you can use _envmytag_type to fetch the 42. The third parameter has been generalized from an unstructured blob of data to a structured collection of environment variables. Slots can even be reused, in which case they behave like FILO queues (stacks). How do you set up new tag ? Is just mytag some mytag_type mytag = {}; ? or should mytag_type inherit/be wrapped from some special stuff As for what is not changing: Grammars, Transforms and Algorithms === It would be wonderful if there were a more natural syntax for describing proto algorithms rather than with structs, function objects, proto::or_, proto::when, and friends. If there is one, I haven't found it yet. On the up side, it means that many current proto-based libraries can be upgraded with little effort. On the down side, the learning curve will still be pretty steep. If anybody has ideas for how to use C++11 to simplify pattern matching and the definition of recursive tree transformation algorithms, I'm all ears. There is not so much way to describe something that looks like a grammar definition anyway. BNF/EBNF is probably the simplest way to do it. Now on the syntactic clutter front, except wrapping everything in round lambda or use object/function call in a hidden decltype call, I don't see what we can do better :s Glad it is picking up steam :D ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] proto-11 progress report
On 6/25/2012 12:39 AM, Joel Falcou wrote: On 06/24/2012 01:10 AM, Eric Niebler wrote: snip int i = LambdaEval()(_1 + 42, 0, proto::tag::data = 8); The 3rd parameter associates the value 8 with the data tag. snip How do you set up new tag ? Is just mytag some mytag_type mytag = {}; ? or should mytag_type inherit/be wrapped from some special stuff Special stuff. Tags are defined as follows: struct my_tag_type : proto::tags::defmy_tag_type { using proto::tags::defmy_tag_type::operator=; }; namespace { constexpr my_tag_type const my_tag = proto::utility::static_constmy_tag_type::value; } The gunk in the unnamed namespace is for strict ODR compliance. A simple global const would be plenty good for most purposes. As for what is not changing: Grammars, Transforms and Algorithms === It would be wonderful if there were a more natural syntax for describing proto algorithms rather than with structs, function objects, proto::or_, proto::when, and friends. If there is one, I haven't found it yet. On the up side, it means that many current proto-based libraries can be upgraded with little effort. On the down side, the learning curve will still be pretty steep. If anybody has ideas for how to use C++11 to simplify pattern matching and the definition of recursive tree transformation algorithms, I'm all ears. There is not so much way to describe something that looks like a grammar definition anyway. BNF/EBNF is probably the simplest way to do it. That would be overkill IMO. Proto grammars don't need to worry about precedence and associativity. Forcing folks to write E?BNF would mean forcing them to think about stuff they don't need to think about. Now on the syntactic clutter front, except wrapping everything in round lambda or use object/function call in a hidden decltype call, I don't see what we can do better :s More round lambda, sure. Fixing inconsistencies, also. But I tend to doubt that using grammar-like expressions in a decltype would be a significant improvement. Folks still can't write transforms in straight, idiomatic C++, which is what I want. Glad it is picking up steam :D C++11 has made this pretty fun. I'm ready to stop supporting all my C++03 libraries now. :-) -- Eric Niebler BoostPro Computing http://www.boostpro.com signature.asc Description: OpenPGP digital signature ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto
Re: [proto] proto-11 progress report
On 24/06/2012 01:10, Eric Niebler wrote: As for what is not changing: Grammars, Transforms and Algorithms === It would be wonderful if there were a more natural syntax for describing proto algorithms rather than with structs, function objects, proto::or_, proto::when, and friends. If there is one, I haven't found it yet. On the up side, it means that many current proto-based libraries can be upgraded with little effort. On the down side, the learning curve will still be pretty steep. If anybody has ideas for how to use C++11 to simplify pattern matching and the definition of recursive tree transformation algorithms, I'm all ears. There is a function which is very simple and that I found to be very useful when dealing with expression trees. unpack(e, f0, f1) which calls f0(f1(e.child0), f1(e.child1), ..., f1(e.childN)) I can do recursion or not with the right f1, and I can 'unpack' an expression to an n-ary operation f0. Here f0 is typically a function that uses its own overloading-based dispatching mechanism. It needs clang trunk to compile. Why doesn't it work with GCC? ___ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto