[Proto] lambda functions with named variables

Dear all, I am thinking of having creatures like lam(x)(x + 2) in my code which would be the Haskell equivalent for \x -> x + 2. In fact, I am working in an untyped world (with very limited functionality) and my typical lambda expressions would only include (function) applications, (lambda) abstractions, and let-bindings. It is exactly for the existence of let-bindings that I guess I can't resort to placeholders like: template<int> placeholder; const terminal<placeholder<0> >::type _1 = {{}}; const terminal<placeholder<1> >::type _2 = {{}}; const terminal<placeholder<2> >::type _3 = {{}}; ... The point is that I need to store what each variable is bound to. And, AFAIK, I can't store such information in std::map<> for _1 has a different type than _2 for example. So, the two hopes that I have in Proto for solving this problem are: 1) To provide a type T instances of which can act like untyped variables in accepting values of different C++ types. T should also be storable in a map-like container. Boost.Any comes to mind for the first requirement but the problem is that there is no meaningful operator < or operator == to use map or unordered_map for boost::any objects. Note that a1 != a2 needs to the case only when a1 and a2 are distinct variables. Can proto::_ be of any help here? 2) To provide a map-like container in which I can store things like boost::any objects. OK, maybe this is not for Proto to address but though it might still have something to offer... TIA, --Hossein

On 11/1/2010 12:59 PM, Manjunath Kudlur wrote:
2) To provide a map-like container in which I can store things like boost::any objects. OK, maybe this is not for Proto to address but though it might still have something to offer...
Have you checked out Boost.Fusion map or vector for this purpose?
Second this. You do *not* want to use boost::any for this as you will lose all type safety and optimization opportunities. Here's the basic strategy: Define tags like this: template<typename T> struct arg_ { typedef T type; }; template<typename T> struct arg : proto::terminal<arg_<T> > {}; struct x_ {}; struct y_ {}; arg<x_>::type const x = {{}}; arg<y_>::type const y = {{}}; Now you have placeholders named x and y to play with. Now this: lam(x, y) should return some object that: 1) Has a member typedef for mpl::vector<x_, y_> 2) Has an operator() member that accepts a Proto expression The operator() in (2) above should return an object that: 1) Holds the Proto expression (by reference) 2) Has the mpl::vector of tags as a member typedef 3) Has an operator() member that accepts arguments for the lambda The operator() in (3) above should have the same arity as the mpl::vector of tags. It should take the arguments and put them in a fusion::vector. Then it takes the mpl::vector of tags and the fusion::vector of arguments and turn it into a fusion::map. This map will be used as the state parameter when evaluating the Proto expression (along with the map) with the following Proto algorithm: struct at_key : proto::callable { template<typename Sig> struct result; template<typename This, typename Map, typename Key> struct result<This(Map, Key)> : fusion::result_of::at_key< typename boost::remove_reference<Map>::type , typename boost::remove_const< typename boost::remove_reference<Key>::type >::type > {}; template<typename Map, typename Key> typename fusion::result_of::at_key<Map, Key>::type operator()(Map & map, Key const &) const { return fusion::at_key<Key>(map); } }; struct LambdaEval : proto::or_< proto::when< proto::terminal<arg_<_> > , at_key(proto::_state, mpl::deref<proto::_value>()) > , proto::_default<LambdaEval> > {}; Have fun! -- Eric Niebler BoostPro Computing http://www.boostpro.com

Hi Manjunath,
2) To provide a map-like container in which I can store things like boost::any objects. OK, maybe this is not for Proto to address but though it might still have something to offer...
Have you checked out Boost.Fusion map or vector for this purpose?
Not really. So, is there any reason what you would recommend that? TIA, --Hossein

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 11/3/2010 11:59 AM, Hossein Haeri wrote:
Hi Manjunath,
2) To provide a map-like container in which I can store things like boost::any objects. OK, maybe this is not for Proto to address but though it might still have something to offer...
Have you checked out Boost.Fusion map or vector for this purpose?
Not really. So, is there any reason what you would recommend that?
Did you see my elaboration on this idea? http://lists.boost.org/boost-users/2010/11/63833.php - -- Eric Niebler BoostPro Computing http://www.boostpro.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJM0ZCVAAoJEAeJsEDfjLbXSeUIAItrR/TUFdSTq4ZOIHztDTkJ 53H9n7jlQ9KYjBRwXat1EMXdKjdlK3ZTsCLtPiVUXiLrYZzNh+xGfAdoohWMUXUc O2p2OQBBtnvszJMP42j/QW58jsKI68ti9heUJyfLES8ddnp0ocWBdoZYLKrMTJCu QGNfBZJU7ylXK4i5/8AdFTpAN3nvnFPeCbS0BYdD7EqFsB+k63xRMNj+TwmAMM0N cXRlpKYkKLilkbfeTWQ+gOqzr4liFnPxTwCkEJSo+67vYSPUjFh0babdfo6fzgwK KsPeLV0e0YEPiMOTOI8Rq7ECpGvhqhM/H5JkK/6/IMrh+n2/UwneZ21HX//7mXc= =SjCa -----END PGP SIGNATURE-----

Dear Eric,
Have you checked out Boost.Fusion map or vector for this purpose?
Not really. So, is there any reason what you would recommend that?
Did you see my elaboration on this idea? http://lists.boost.org/boost-users/2010/11/63833.php
Yes, but, in fact, you're too quick for me. I've only started to read about Proto. So, there are lots of points in your code that I don't understand. I'm gradually going through the Proto documentation only in my spare time. I see your code -- as well as the other friend here at Boost -- suggest checking Fusion vectors. That's piles onto my stack and I'll get there soon I hope. I thought, in the mean time, you might provide some shortcuts for my journey to the heart of Fusion. And, that's the reason why I asked what's so special about them (for my application)? And, BTW, thank you very much for your cool cpp-next articles. So inspiring... :) TTFN, --Hossein
participants (3)
-
Eric Niebler
-
Hossein Haeri
-
Manjunath Kudlur