
Hi all, I'm writing a review of phoenix, but first I have a some questions and notes. * First of all, it is not clear to me how 'lambda' works. I would have thought that it just introduced a new scope, but it seems that it does something more: 1: int i = 10; 2: cout << arg1(i) <<endl; 3: cout << lambda[ arg1 ](i) <<endl; // doesn't compile 4: cout << lambda[ arg1 ]()(i) The use of lambda at line 3 is completely superfluous, nevertheless, I prefer that syntax because it makes it clear that I'm using a lambda expression (always using lambda will also allow some other tricks I'll discuss later). Surprisingly, line 3 doesn't compile. lambda::operator[] actually returns a nullary stub that must be evaluated to actually get our unary function. Is this really necessary? can it be fixed? * non-standard result<> protocol. IMHO for Phoenix to become a first class boost library, it should support result_of out of the box. I understand that this is not done for backward compatibility, but I think that there are three solutions: 1) old users will still be able to use the Phoenix inside spirit if they have a large codebase that uses the old protocol. 2) phoenix could provide a wrapper that converts from the old to the new protocol and viceversa. This would require some changes in the client code. 3) phoenix could detect the protocol used by the user function and switch between the old and new 'result'. This is hard to do in a robust way, but breaks no user code. I would prefer the first option. * Perfect forwarding. I'm used to the perfect forwarding in boost lambda (which, contrary to what the documentation states, perfectly forwards up to 3 args). Personally have little use for lambdas that take their arguments by non const reference as I strive for referential transparency. I know that implementing this feature has an high compile time cost, but there should at least be an option to enable it. I would vote for two additional 'lambda' syntaxes: clambda and plambda (better names are wellcome). The first one would work like boost lambda const_arguments and should have no compile time cost, while the second will do perfect forwarding up to some parameter number. This would require the lambda[] syntax to actually return the wrapped function object, not a stub (as per first question). * operator->*. I sometimes use this operator with boost lambda, as a short hand for binding member functions, but, as in phoenix, it requires it lhs to be a pointer. Would it possible to extend it to any functions? for example: struct foo { int bar; }; std::vector<foo> in =...; std::vector<int> out; std::transform(in.begin(), in.end(), std::back_inserter(out), (&arg1)->*&foo::bar); The parenthesis, and ampersand are ugly, it would be great if this worked: std::transform(in.begin(), in.end(), std::back_inserter(out), arg1->*&foo::bar); I think this would interfere with foo implementing its own operator->*. Which brings the question... * ... how do I implement type deduction for the my own overloaded operators? I.e. what is the phoenix equivalent of http://tinyurl.com/4botne ? By reading of the documentation I couldn't figure out an easy way to do it. Well, that's all for now, those questions are mostly to get the discussion rolling, more to come. -- gpd