[Proto?][Phoenix?] : Advice on creating lazy data structures
With Phoenix or lambda-like DSELs implemented with Proto, it is easy to implement stuff when the expected actual parameters to the lambda expressions are primitive types. When I want to pass arbitrary types to the lambda expression and manipulate it in the lambda expression, things become complex. For example, consider the following function : struct point { float x; float y; }; float sum(point p) { return p.x+p.y; } If I want to have a lazy version of this function, I cannot simply do (arg1.x + arg1.y)(p). I have to implement functions that return Proto or Phoenix expressions and use it in the language. In the above case, it would look something like (point_get_x_(arg1) + point_get_y_(arg2))(p). So for every type I want to support in the DSEL, I have to implement lazy versions of functions to get and set the type members, or call some methods. In other words, the language has to be aware of all the data types that can be used with it. I am looking for some advice on a standard or a generic way for creating such lazy data structures. Has something like this been done before? I will be grateful for any pointers and suggestions. Thanks, Manjunath
On 3/30/2010 2:02 PM, Manjunath Kudlur wrote:
With Phoenix or lambda-like DSELs implemented with Proto, it is easy to implement stuff when the expected actual parameters to the lambda expressions are primitive types. When I want to pass arbitrary types to the lambda expression and manipulate it in the lambda expression, things become complex. For example, consider the following function :
struct point { float x; float y; };
float sum(point p) { return p.x+p.y; }
If I want to have a lazy version of this function, I cannot simply do (arg1.x + arg1.y)(p). I have to implement functions that return Proto or Phoenix expressions and use it in the language. In the above case, it would look something like (point_get_x_(arg1) + point_get_y_(arg2))(p). So for every type I want to support in the DSEL, I have to implement lazy versions of functions to get and set the type members, or call some methods. In other words, the language has to be aware of all the data types that can be used with it. <snip>
Not necessarily. These these can be added to your DSEL post-hoc, and
there are some fun games you can play with proto's operator->*. Consider
the following program:
#include <cassert>
#include
<snip>
Not necessarily. These these can be added to your DSEL post-hoc, and there are some fun games you can play with proto's operator->*. Consider the following program:
Thanks, Eric. That was an Ah-ha moment for me. I tried a different
variation of your program. I changed point to a templated
tuple
, proto::otherwise<
proto::_default
{} eval;
using namespace std;
int main()
{
tuple
Thanks, Eric. That was an Ah-ha moment for me. I tried a different variation of your program. I changed point to a templated tuple
and declared the terminals x and y with proto::_ template arguments. Here is the complete program :
I re-worked the program as below to achieve what I need. But now,
using the DSEL with a new data-type becomes much more invasive,
because I need some rules to the grammar. May be there is a less
invasive and more elegant way? Also, I don't understand why I need
both This(tuple<>&) and This(const tuple<>&) versions in the
get_tuple_* classes. Removing either one of them causes a compiler
error.
#include <cassert>
#include
{} eval;
using namespace std;
int main()
{
tuple
On 3/30/2010 12:48 PM, Manjunath Kudlur wrote:
Thanks, Eric. That was an Ah-ha moment for me. I tried a different variation of your program. I changed point to a templated tuple
and declared the terminals x and y with proto::_ template arguments. Here is the complete program :
<snip>
Sorry for the delay. I've been away from my computer. This is indeed a
tricky problem. The trick is to realize that grammars can be made open
and extensible in a variety of ways. The simple is to define a
customization point. What you need is a way to plug into an existing
grammar new classes and members. Define a get_member_ptr template that
users of your grammar can use to make it aware of third-party types.
Code attached below:
#include <cassert>
#include <iostream>
#include
participants (2)
-
Eric Niebler
-
Manjunath Kudlur