
On 24/02/2011 19:07, Thomas Heller wrote:
On Thu, Feb 24, 2011 at 5:52 PM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
---- Phoenix v3 is missing a phoenix.hpp header file that includes all modules, which Phoenix v2 had (but in the parent directory).
Nope, its not, there is the boost/phoenix/phoenix.hpp header which includes all of phoenix. IIUC it is generally frowned upon to put those headers directly in the boost directory.
It must be recent then, because I didn't have it in my not entirely up to date checkout of the sandbox.
Lazy functions -------------- Using phoenix::function to turn a PFO into a lazy function is the most basic way to extend Phoenix with new functionality, and clearly the recommended way to do so according to the docs. [1] [2] It is directly inherited from Phoenix v2, and only the result type deduction mechanism changed.
Correct. But please keep in mind. You as a user don't have to put your phoenix::function objects at some namespace scope.
This approach has several problems, at least in the way it is presented in the documentation. - global objects potentially increase binary size - those objects are not PODs and therefore requires runtime initialization, adding some runtime overhead at application startup - instantiation happens regardless of whether the function is used or not, which affects compilation time negatively.
Do you have numbers for that?
This method is massively used to define a whole lot of lazy functions that forward to standard algorithms and container functions [3], which suggests that this is indeed the recommended way to proceed. It should however be avoided; prefer defining a template function that constructs and applies the adapted function object, if the function object can stay a POD that's better too.
Do you have concrete proposal how this could look like? If there is no significant impact on (compile and runtime) performance of the points you mentioned above, it will stay as it is for now.
I'll let Joel Falcou do that.
It is not redundant. The thing is that proto only recognizes one tag for a terminal expression. To distinguish between all those different terminal types, we needed the custom terminal customization point.
I was thinking phoenix::ref could be a proto node, but that doesn't quite work because Proto catches terminals by value (isn't there a way to customize that though? -- I'm not familiar with that kind of thing)
Phoenix as Proto with statements --------------------------------
One thing I was hoping Phoenix v3 would be is Proto extended to support statements.
I don't understand, what do you mean by that?
Proto is a tool to write domain-specific embedded languages based on C++ expressions. It's like a compiler framework, but the AST is limited to expressions and cannot contain function creation, local variable definition, or repetition. It would be nice to have a tool like Proto but that was extended to deal with more C++ language constructs. Even if the syntax to call them requires transforming those constructs to expressions with a DSEL of its own, at least there can be a canonic way to do so.
While it comes pretty for some uses, it still fails one one point: the ability to define custom languages that embed Phoenix statements.
The ability is there ...
The missing piece is handling of domains (extends are missing too, but I don't think they make sense at the statement level).
... and you don't need necessarily need the proto domain feature for that.
Phoenix doesn't really help with things like phoenix::if_(1)[some_expr_in_my_own_domain] If things are necessarily in the phoenix domain, that's not really your custom language. That's like using Proto without domains. I think it needs to be a parametric domain, like phoenix of common domain of what's inside. Being able to tell how Proto expressions within Phoenix should be evaluated on a per-domain basis seems important too. I have no idea how to evaluate a Phoenix expression containing other Proto expressions with the current design.
Documentation ------------- <http://svn.boost.org/svn/boost/sandbox/SOC/2010/phoenix3/libs/phoenix/doc/html/phoenix/actor.html> doesn't talk about perfect forwarding.
It is mentioned here: http://svn.boost.org/svn/boost/sandbox/SOC/2010/phoenix3/libs/phoenix/doc/ht...
Yes, but the page I referenced shouldn't only list non-const reference overloads: that's confusing.
We can only *emulate* perfect forwarding. THe sentence you claim is wrong is just a reformulation of the "Perfect Forwarding Problem" (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm) problem statement.
Then the original problem statement is misleading. It is later said in the paper that they don't consider solutions that scale worse than linearly to be good enough. Solution #3, that they do list, works fine with C++03 language rules, but is discarded due to its cost in number of overloads. I don't really see where the term "emulation" comes from. Forwarding arguments is forwarding arguments, you just have to make sure you can catch all arguments without loss of information, there is no hack or emulation involved. A better phrasing would involve saying that is is not impossible, but rather requires an impractical amount of work. I wonder how much that amount of work is really a problem with preprocessed Phoenix though.