
Hi Huang, On 01/04/2012 05:05 AM, Huang Huan wrote:
Yes, Boost.Phoenix do a lot forward in unname function. Unfortunately the presented features are not found in it.
2012/1/4 Mathias Gaunard<mathias.gaunard@ens-lyon.org>
return is hard to implement, since each expression is building its own expression, so you need to forward it along the whole chain. Exceptions could also be used, but it's not very nice.
return is the most usefull part of function. I'm working on the implement, it's approved work with no exception for return. The architect is defferent from the lambda, I think the phoenix is also . The final functional call is wrapped, and create a heap/stack like workspace. It will support restore for yielding calls. and yielding& local var are also involved in the return architect.
I agree, "return" is very useful when you want to stay as close to C++ as possible. However, returning a value is highly unusual in functional programming and if there is something like returning something it is implemented as a Monad. Additionally i found it overly complex to implement a return statement. It would require deep introspection of the expression at hand to check if there is a return statement inside the expression to calculate the return type. Additionally, it is rather hard to deal with diverging return types (though a variant could be used here) or to output meaningful error messages (something which i would like to focus on in the next releases). Please note that I am not saying it is impossible to do that with phoenix, quite the contrary.
Boost.Phoenix provides local variables using let/in syntax.
let(_a = 1)[...] I think the let syntx is a worse way, and you may make some mistak of my way. The let syntx is quite different from the C++ style, and _a ... _z are limited.
The let syntax was chosen to mimic the style of traditional functional programming languages. Which is in contrast to the initial advertisement of phoenix stating it is "C++ in C++". In fact, the scope module is probably the place where Phoenix differs the most from traditional C++ syntax. Mainly due to the fact that things like this weren't really possible in C++ when Phoenix was invented. Joel might have some more insight on his motivation to chose that syntax! _a to _z are just some predefined local variable names. You can define your own names, with your own tags.
I have implement the major part of my way, and some syntax have changed as below:
// this macro is define in the lib define, use local_var_name<int id> #define var_name(x) local_var_name<__LINE__> x; // example begin here struct A { A() {}; A(char ch) {}; };
var_name(x); // just predefine the name in no type for lambda using. var_name(y); // one single line for one var_name, the macro could be redefined add some unuse code for unique line protect. var_name(z); ( ( // declaring use local_var, scope begin here local_var<A> (x) , // default construct A::A() local_var<A> (y) ('a') , // construct<A>('a') A::A(char) local_var<A> (z) (x) , // copy construct A::A(A const&) x = y // assignment A::operator=(A const&) ), ( x,y,z, // error, out of scope ) ) p.s. 1. the phoenix omitted the different way of construct/copy/assignment. 2. free style identifier name, better for code reader.
Your described syntax isn't that different from Pheonix. Phoenix supports the copy constructor and assignment operator. Additionally, Phoenix provides construct<A> which can be used to create instances of objects. However, I agree, that having a "free style identifier" name would greatly improve Phoenix.
Actually I have rewrote lambda, it support return/yielding, most operators, part of local var, without bind. I want to join the dev of Boost.Phoenix, if can how?
I am one of the authors, Joel de Guzman is the main author and inventor of Phoenix. Patches and ideas are always welcome! Best Regards, Thomas