-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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.
Expressions vs. Grammars ======================== Many new users are confused by the difference between terminal<int> and terminal<int>::type. In proto.next, there is no difference. Forget the ::type. Things just work. 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> { template<typename E, typename ...Rest> auto operator()(E && e, Rest &&...) const BOOST_PROTO_AUTO_RETURN( static_cast<E &&>(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.) 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 _env<mytag_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). proto::callable and proto::is_callable will no longer be necessary ================================================================== Much work has gone into eliminating the need for proto::callable and proto::is_callable. The present need comes from a difference between the proto call and make transforms. In make<X(Y)>, X is treated as a lambda describing a type. For instance, X might be std::vector<proto::_value>, in which case, proto::_value is evaluated and the result (say, int) is used to instantiate vector. proto::call doesn't do that, and that decision has caused no end of grief. In proto.next, a transform like X(Y) is evaluated by first treating X as a lambda like make does today. After a real type has been computed, it's safe to ask whether the new type is a transform, callable or other. Transforms are quite simply anything that has inherited from proto::transform. And in C++11, there is no reason to tag something as callable or not; extended SFINAE can do the job for us. Either X()(y) compiles or it doesn't. As a result, proto can easily and reliably distinguish callable transforms from object transforms with no help from the user. 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. For those curious to taking a peek, the code lives here: https://github.com/ericniebler/home/tree/master/src/proto It needs clang trunk to compile. I also had to manually fix a bug in my gcc headers to get the tests to compile. This is still in a very raw state, and not useful for real work yet. - -- Eric Niebler BoostPro Computing http://www.boostpro.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJP5kzWAAoJEAeJsEDfjLbX+S4H/2n3p7jILN6uFTqGY/9OZwxY /DBKIZDyRPbNtDXaEfPSelMjrszubdg577MCnl2+mE8zONEmImP8qPACnJUGBoA3 4N4FBn1q9BGcmJYlDlb2lw5tT3znS/DoXPEJSdgWT5lRKsJLQ2cuBIjLdePeicg3 vLfMUfo+bgW+ut/MIqEJ3VpaIAzACPhVbm/+cj17qGgF7GEis/Dd3uYrccrh+nA/ wJcq3RD+xHm1VbtDPdenkbRyjtu0gVQ4qGINRs6URmLypmwcFbjQSN+ydkDN3VDj mb1sC06L5o1i+c/g/b6+2a2B/18tRTLW7e4/rcpeAlJvSBErjdxkC/9LmJWXUHQ= =QbhO -----END PGP SIGNATURE----- _______________________________________________ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto