Eric Niebler wrote:

> On Mon, Oct 4, 2010 at 12:43 PM, Thomas Heller
> <thom.heller-gM/ye1e23mwn+bqq9rb...@public.gmane.org>wrote:
<snip>
>>
>> >
>> > I'll also point out that this solution is FAR more verbose that the
>> > original which duplicated part of the grammar. I also played with such
>> > visitors, but every solution I came up with suffered from this same
>> > verbosity problem.
>>
>> Ok, the verbosity is a problem, agreed. I invented this because of
>> phoenix, actually. As a use case i wrote a small prototype with a
>> constant folder:
>>
>> 
http://github.com/sithhell/boosties/blob/master/proto/libs/proto/test/phoenix_test.cpp
>>
>>
> Neat! You're getting very good at Proto. :-)

Thanks :)
Let me comment on your request:

On Tuesday 05 October 2010 03:15:27 Eric Niebler wrote:
> I'm looking at this code now, and perhaps my IQ has dropped lately
> (possible), but I can't for the life of me figure out what I'm looking
> at. I'm missing the big picture. Can you describe the architecture of
> this design at a high level? Also, what the customization points are and
> how they are supposed to be used? I'm a bit lost. :-(

First, let me emphasize that I try to explain this code:
http://github.com/sithhell/boosties/blob/master/proto/libs/proto/test/phoenix_test.cpp

Ok, i feared this would happen, forgive me the low amount of comments in the 
code and let me start with my considerations for this new prototype.

During the last discussions it became clear that the current design wasn't 
as good as it seems to be, it suffered from some serious limitations. The 
main limitation was that data and algorithm wasn't clearly separated meaning 
that every phoenix expression intrinsically carried it's behavior/"how to 
evaluate this expression".
This was the main motivation behind this new design, the other motivation 
was to simplify certain other customization points.
One of the main requirements i set myself was that the major part of 
phoenix3 which is already written and works, should not be subject to too 
much change.

Ok, first things first. After some input from Eric it became clear that 
phoenix expressions might just be regular proto expressions, wrapped around 
the phoenix actor carrying a custom tag. This tag should determine that it 
really is a custom phoenix expression, and the phoenix evaluation scheme 
should be able to customize the evaluation on these tags.
Let me remind you that most phoenix expressions can be handled by proto's 
default transform, meaning that we want to reuse that wherever possible, and 
just tackle the phoenix parts like argument placeholders, control flow 
statements and such.
Sidenote: It also became clear that phoenix::value and phoenix::reference 
can be just mere proto terminals.

Having that said, just having "plain" evaluation of phoenix expressions 
seemed to me that it is wasting of what could become possible with the power 
of proto. I want to do more with phoenix expressions, let me remind you that 
phoenix is "C++ in C++" and with that i want to be able to write some cool 
algorithms transforming these proto expressions, introspect these proto 
expression and actively influence the way these phoenix expressions get 
evaluated/optimized/whatever. One application of these custom evaluations 
that came to my mind was constant folding, so i implemented it on top of my 
new prototype. The possibilities are endless: A proper design will enable 
such things as multistage programming: imagine an evaluator which does not 
compute the result, but translate a phoenix expression to a string which can 
be compiled by an openCL/CUDA/shader compiler. Another thing might be auto 
parallelization of phoenix expression (of course, we are far away from that, 
we would need a proper graph library for that). Nevertheless, these were 
some thoughts I had in mind.

This is the very big picture.

Let me continue to explain the customization points I have in this design:

First things first, it is very easy to add new expression types by 
specifying:
   1) The new tag of the expression.
   2) The way how to create this new expression, and thus building up the 
      expression template tree.
   3) Hook onto the evaluation mechanism
   4) Write other evaluators which just influence your newly created tag 
      based expression or all the other already existing tags

Let me guide you through this process in detail by explaining what has been 
done for the placeholder "extension" to proto (I reference the line numbers 
of my prototype).

1) define the tag tag::argument: line 307
2) specify how to create this expression: line 309 to 315
      First, define a valid proto expression line 309 through phoenix_expr 
      which had stuff like proto::plus and such as archetypes. The thing it 
      does, it creates a valid proto grammar and transform which can be 
      reused in proto grammars and transforms, just like proto::plus.
      Second, we create some constant expressions which are to be used as 
      placeholders
3) Hook onto the evaluation mechanism: line 321 to 361
   Note: i created a unpack transform which is boilerplate code for the 
         extraction of the children of the current node. So what it does is, 
         that it calls the proto::callable passed as first template 
         parameter and is applies an optional transform to the children 
         prior to passing it to the callable, additionally it is able to 
         forward the data and state to the transform
   in line 320 to 323 we define the specialization of our generic_evaluator 
   which dispatches the call to argument_eval through the unwrap transform.
   The remaining part (line 325 to 361) does not differ too much from the 
   current design.

That is basically what needed to be done to supply phoenix with a 
placeholder. I also added the if/else statements to the prototype which 
follows the same principles.

The lines 494 to 593 are just a test to check whether the phoenix 
expressions really can be used as a proto grammar, and show how it could be 
possible to introspect phoenix expressions.

The next big thing is probably the constant folder, which shows how 4) can 
be realized and is an example of this customization point.

Another example which only influences one tag, and only that tag could be 
the split example which could have been easily embedded into this phoenix 
context, and the custom evaluation would have only influenced the split 
expressions. Additionally, this is where this visitor plays out it strength:
With the ability to tag dispatch on both, the grammar and the evaluation, 
one can easily restrict expression which should _not_ be inside a split 
expression.

That is all for now, i hope i made this prototype a little clearer and sched 
some light on my motivations.

> P.S. It would be great if you could repost this code along with your
> explanation to the proto list. I suspect this redesign is part of the
> motivation for the recent messages you posted there, right?
Right. Consider it done by this message ;)
 
> 
>> Note that the phoenix grammar could end up growing very complex! But
>> users should still be able to add their own tags for their own
>> expressions. I decided to propose the visitor because Joel Falcou
>> showed interest in it (Because he invented something similiar for NT2,
>> remember one of the first prototypes for phoenix3? They were actually
>> based on the same concepts).
>>
> 
> We abandoned those early prototypes. Now I can't remember why. Can you?

As far as my memories go, we abandoned those prototypes because of several 
reasons, one was that this early prototype was quite complex and not very 
easy to follow, i guess this is true for my attempt to resurrect it. The 
other thing was that people felt like we exposed too much of proto to users 
who wanted to extend phoenix. Last but least, it differed too much from the 
design of phoenix2. See my explanations above on my try to tackle the 
criticism on all these points.
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to