Re: [proto] My own lambda for MSM / wish list

2011-03-24 Thread Mathias Gaunard

On 14/03/2011 22:12, Christophe Henry wrote:

Calling phoenix expressions from the statement module return void.
Calling phoenix expressions from any other modules return whatever ... depending on the 
"C++-Sense".


It's ok, I can live with it, though I'll need to find a way around
because I do need this return stuff.


return in phoenix is not really easily implementable.
setjmp / longjmp is probably the only way to do it well.
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-16 Thread Christophe Henry
>Well, because it wasn't possible at the time, I assume ;)
>Times have changed since then ...

Indeed. Looks like it. :)

>> What I wanted to know:
>> - can I pass a phoenix expression to a decltype / BOOST_TYPEOF and
>> default-construct it?


>In general, no, because of various terminals that need to be initialized.
>You can however limit the phoenix grammar to only those expressions that can 
>be default constructed.

If you mean all except, say, ints or chars, it's something I can live
with because I already do ;-)

>Why not copy construct them?

I don't see how it would help. I mean, the transition table I'm
generating with the grammar ist and mpl::vector< Row<...>, Row<...> >.
Then run my metaprograms and I have nothing left to construct from.

>Yes, the entry point is pretty high, but i hope its worth it ... If you come 
>to the conclusion that writing your own library is faster and easier phoenix 
>maybe isn't quite >ready for prime time with that respect.

No, it's not what I mean. The library is already written, since about
1 year, it's inside MSM's eUML front-end (see for example
http://www.boost.org/doc/libs/1_46_0/libs/msm/doc/HTML/ch03s04.html#d0e2059).

But the implementation will not win a beauty contest ;-)
So I'm rewriting it and the examples I presented in this thread are
only a cleaned-up, smaller version to show what I'm looking for, with
some stuff I added after I realized it was not usable only with MSM.
Now that I tried to explain what I was looking for and after your
answers and some time I just spent investigating phoenix, I think it's
worth giving a try with phoenix.

So if you accept helping me a bit to come to speed with phoenix
internals, I think MSM can pretty fast be your first "client" ;-)
If you don't mind, I offer to close this thread and start hacking
code. I already have the first questions ready.

>I am looking forward to improvments in the docs, or additions to code you 
>might have!

Sure, we'll see on the way what I'm missing.

Thanks,
Christophe
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-16 Thread Thomas Heller
On Monday, March 14, 2011 10:12:09 PM Christophe Henry wrote:
> >Calling phoenix expressions from the statement module return void.
> >Calling phoenix expressions from any other modules return whatever ...
> >depending on the "C++-Sense".
> 
> It's ok, I can live with it, though I'll need to find a way around
> because I do need this return stuff.
> 
> >> If you allow a short criticism, I'd say that phoenix is great and
> >> maybe even offers all I want, but the doc is doing it a great
> >> disservice. I got so frustrated I started my own implementation and
> >> seeing my lack of time, it means something ;-)
> >
> >Maybe you should have asked before you started re-implementing
> >everything ;)
> 
> And maybe I did ;-)
> As a matter of fact, I did, twice. First at the BoostCon09 I talked
> about it with JdG, but my question was not well formulated, so I'm not
> sure he got what I wanted to do.
> Second time at BoostCon10, I mentioned it during my talk and Eric's
> view was that what I wanted to do was not possible with the state of
> Phoenix at that time (though maybe I again failed to explain my
> point).

Well, because it wasn't possible at the time, I assume ;)
Times have changed since then ... 

> Then I had a look at the doc and still didn't find my answers.
> 
> So, I decided to invest some time (not too long) to present using a
> basic implementation what I was looking for.
> At least with this example, it's easier to discuss, I can ask much
> more targeted questions and I had a lot of fun in the process :)
> 
> >Phoenix comes with a whole bunch of testcases, which can be seen as
> >examples as well.
> 
> I had a look at that too, but I looked at the "statement" testcases,
> which still didn't answer my question about return types. True, I
> didn't think of looking into "operator".

Sure ... the things about return types can't be found in the examples ... To 
quote the docs:

"Unlike lazy functions and lazy operators, lazy statements always return 
void."
https://svn.boost.org/svn/boost/trunk/libs/phoenix/doc/html/phoenix/modules/statement.html



> >I tried to document the internals. What do you think is missing?
> >The questions you had could have all been solved by looking at the
> >documentation, there wasn't any need to know the internals.
> 
> What I wanted to know:
> - can I pass a phoenix expression to a decltype / BOOST_TYPEOF and
> default-construct it?

In general, no, because of various terminals that need to be initialized.
You can however limit the phoenix grammar to only those expressions that can 
be default constructed.
Why not copy construct them?

> - what is the return value of a phoenix expression?

boost::result_of::type

This is a little hidden in the docs ... but its all here:
https://svn.boost.org/svn/boost/trunk/libs/phoenix/doc/html/phoenix/inside/actor.html

Follow the link to "Polymorphic Function Object".

> - how do I add stuff I want (return for ex.)

https://svn.boost.org/svn/boost/trunk/doc/html/phoenix/examples/adding_an_expression.html

> Do I really find this in the doc?
> With the ref/cref inside the lambda, it's also not shown, but I admit
> I could have thought about it by myself.
> 
> >Ok, I admit, the whole capture by value semantics probably isn't
> >discussed at full length. Of course there is always room for
> >improvement! Do you have anything specific?
> 
> Ah, value semantics isn't my main interest anyway. Where I really
> started to doubt was reading the internals section, then I came to
> this:
> 
> // Transform plus to minus
> template <>
> struct invert_actions::when
> 
> : proto::call<
> 
> proto::functional::make_expr(
> phoenix::evaluator(proto::_left, phoenix::_context)
>   , phoenix::evaluator(proto::_right, phoenix::_context)
> )
> 
> {};
> 
> I understand a bit of proto but this mix of proto:: and phoenix:: is
> just killing me. It just doesn't fit into my standard design layered
> model. Either I work at the proto layer, or at the phoenix layer, not
> at both. Having to understand both is simply increasing the cost of
> playing with phoenix.

Well, the phoenix internals are all implemented using proto ... if you dive 
deep into the actions you need both, stuff from proto and stuff from 
phoenix. This part of the library is just proto using stuff that was defined 
within phoenix ... 
You need to know what the evaluator and what actions are:
https://svn.boost.org/svn/boost/trunk/libs/phoenix/doc/html/phoenix/inside/actor.html#phoenix.inside.actor.evaluation
https://svn.boost.org/svn/boost/trunk/libs/phoenix/doc/html/phoenix/inside/actions.html
 
> Now, I have the feeling you think I'm here for a round of phoenix
> bashing. It can't be less true. I'm a big admirer of Joel's work and I
> think phoenix is a really cool library. My problem is simple, I want
> to combine ET with decltype and bring it into new places (MSM, MPL,
> proto for example), and I need to answer 2 questions:
> - can phoenix fulfill my 

Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Joel Falcou

On 14/03/11 22:28, Christophe Henry wrote:

.. the talk from Matt Calabrese last year at boostcon with the
MPL/Fusion hybrid
using decltype and auto. I think this is an interesting venture all in
all and should
be extended.

Yes, I have this in mind too.


I think it is worthy of *at least* consideration. MAtt said some stuff 
was still edgy but the core is probably here.



Sure! Count me in!


And add Gordon to the pool. As for who working when and how long, take 
into consideration i have some part of my own
research programm trying to get started on that, so I can dedicate more 
than just my free time to this.

___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Gordon Woodhull

On Mar 14, 2011, at 5:28 PM, Christophe Henry wrote:

>> .. the talk from Matt Calabrese last year at boostcon with the
>> MPL/Fusion hybrid
>> using decltype and auto. I think this is an interesting venture all in
>> all and should
>> be extended.

Personally, I think it's interesting but I like having a different syntax for 
metaprogramming than for run-time programming; I think it makes things more 
clear.  

I don't actually think having a different syntax will make metaprogramming any 
less difficult for newbies to understand.

But I still would like to help out, if possible, just cuz it's neat stuff.  :-)
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Christophe Henry
> .. the talk from Matt Calabrese last year at boostcon with the
> MPL/Fusion hybrid
> using decltype and auto. I think this is an interesting venture all in
> all and should
> be extended.

Yes, I have this in mind too.

> I have the same kind of ideas Christophe plus a few other (including a
> real meta-DAG structure).
> Maybe we should get Matt in our boat and try hammering stuff ?

Sure! Count me in!
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Christophe Henry
Hi Eric,

>First let me say that I have limited bandwidth at the moment, and apologize in 
>advance for my short reply...

No need to apologize, I can understand this ;-)


>And what you need is for the type of the Proto expression generated by
>"(g1 || g2) && !g3" to be default-constructable? Have you tried doing
>this with an expression adaptor and a domain in which child nodes are
>all held by value (because reference members cannot be
>default-constructed)? What errors did you run into?

I'm sorry to tell you this, but I'm afraid you think I know much more
than I really do ;-)
Sounds great, but how would I do this?

>I don't see how that could ever work. Any way you slice it, (_1 < _2) is
>an expression, not a type. decltype(_1 < _2) could be made to work, for
>some suitably defined _1, _2, and <. And yes, (_1 < _2) would need to be
>default-constructable.

Of course I don't think it could. I can still define an ideal and see
how close I can get.

>> std::transform(vec.begin(),vec.end(),vec.begin(),
>> if_(_1)[ ++_1,return_(++_1)].else_ [return_(++_1)]  );

>This just looks like Phoenix. Why can't you use it directly?

It sure does, but I'm wondering if I'll be cheaper with phoenix than
with my very simple grammar, which I at least about understand ;-)


>> I have at least 2 more:
>>
>> - MPL. Great great library, but the template syntax is keeping too
>> many away from it.
>> I want what the FTMPL guys are doing (hi Matt, hi Zach).
>> I'd really prefer to write _1 + _2 instead of plus<_1,_2>

>You're talking about a complete C++0x redesign of MPL. Doable, but a big job.


I'm not in a hurry and probably not alone with this idea ;-)


>> - proto. Yes, proto itself. Eric talked about it in his BoostCon10
>> talk. Why not write
>> when_() || when_()
>> instead of proto::or< proto::when<>, proto::when<> >
>> Now this is really perverse. A proto grammar to generate... proto. I love it!

>I love it, too! Are you volunteering? ;-) A whole-hog redesign of proto
>for C++0x, taking full advantage of decltype to allow syntax like that,
>is one of those things I wish I had time for.

Why not? ;-)
Though my knowledge of proto is too limited to do it alone. I'd be
happy to help though. This is the second reason I wrote my own
mini-phoenix, learning by doing.


>Exciting stuff! Truly Christophe, your ideas re decltype and EDSLs in
>C++ are revolutionary. But unfortunately, I fear it will require a
>revolution. This is all do-able, but the changes to MPL, Proto and even
>to Phoenix in the case of the lambda capture stuff would require
>breaking API changes.

French have some experience with revolutions ;-)
Seriously I bet quite a few would love to do it too and it could be
great fun. Joel, Matt? *wink* :)

>As for MPL and Proto, someone needs to sit down and do some hard
>thinking about what meta-programming will look like in C++0x. I suspect
>it'll look less like today's MPL and Proto, and much more like what you
>envision. It's a huge opportunity for someone to do some really
>ground-breaking work.

After you write this, it won't be too hard to find candidates :)

Christophe
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Christophe Henry
>Calling phoenix expressions from the statement module return void.
>Calling phoenix expressions from any other modules return whatever ... 
>depending on the "C++-Sense".

It's ok, I can live with it, though I'll need to find a way around
because I do need this return stuff.

>> If you allow a short criticism, I'd say that phoenix is great and
>> maybe even offers all I want, but the doc is doing it a great
>> disservice. I got so frustrated I started my own implementation and
>> seeing my lack of time, it means something ;-)

>Maybe you should have asked before you started re-implementing everything ;)

And maybe I did ;-)
As a matter of fact, I did, twice. First at the BoostCon09 I talked
about it with JdG, but my question was not well formulated, so I'm not
sure he got what I wanted to do.
Second time at BoostCon10, I mentioned it during my talk and Eric's
view was that what I wanted to do was not possible with the state of
Phoenix at that time (though maybe I again failed to explain my
point).
Then I had a look at the doc and still didn't find my answers.

So, I decided to invest some time (not too long) to present using a
basic implementation what I was looking for.
At least with this example, it's easier to discuss, I can ask much
more targeted questions and I had a lot of fun in the process :)

>Phoenix comes with a whole bunch of testcases, which can be seen as examples 
>as well.

I had a look at that too, but I looked at the "statement" testcases,
which still didn't answer my question about return types. True, I
didn't think of looking into "operator".

>I tried to document the internals. What do you think is missing?
>The questions you had could have all been solved by looking at the 
>documentation, there wasn't any need to know the internals.

What I wanted to know:
- can I pass a phoenix expression to a decltype / BOOST_TYPEOF and
default-construct it?
- what is the return value of a phoenix expression?
- how do I add stuff I want (return for ex.)

Do I really find this in the doc?
With the ref/cref inside the lambda, it's also not shown, but I admit
I could have thought about it by myself.

>Ok, I admit, the whole capture by value semantics probably isn't discussed at 
>full length.
>Of course there is always room for improvement! Do you have anything specific?

Ah, value semantics isn't my main interest anyway. Where I really
started to doubt was reading the internals section, then I came to
this:

// Transform plus to minus
template <>
struct invert_actions::when
: proto::call<
proto::functional::make_expr(
phoenix::evaluator(proto::_left, phoenix::_context)
  , phoenix::evaluator(proto::_right, phoenix::_context)
)
>
{};

I understand a bit of proto but this mix of proto:: and phoenix:: is
just killing me. It just doesn't fit into my standard design layered
model. Either I work at the proto layer, or at the phoenix layer, not
at both. Having to understand both is simply increasing the cost of
playing with phoenix.

Now, I have the feeling you think I'm here for a round of phoenix
bashing. It can't be less true. I'm a big admirer of Joel's work and I
think phoenix is a really cool library. My problem is simple, I want
to combine ET with decltype and bring it into new places (MSM, MPL,
proto for example), and I need to answer 2 questions:
- can phoenix fulfill my needs? (it seems it does, great!)
- do I arrive there faster than with my own grammar as phoenix's cost
of entry is pretty high?

Ok, I'll give a second try to phoenix and see how far I can go.

Thanks for your answers,
Christophe
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Thomas Heller
On Monday, March 14, 2011 01:39:41 PM Christophe Henry wrote:
> Hi Thomas,
> 
> >> Row < source_state , event , target_state, action , guard >
> >
> >I suggest you to look into spirit how semantic actions are dealt with, it 
reminds me of exactly this:
> Ok I will, thanks.

Keep in mind, spirit uses Phoenix V2, but the idea is the same ...

> >Phoenix actors are POD, they are default constractible. Do you have a
> >testcase where this is not the case?
> 
> Unfortunately no more, it was quite some time ago, maybe I did it with
> V2. I got something which was not usable by BOOST_TYPEOF.
> I'll try it again.
> 
> >> std::set s2;
> >
> >As Eric noted, decltype is the answer. I can't see why this should not
> >be possible within phoenix.
> 
> Wait, I'm confused, it IS possible, or it SHOULD be possible? Can I
> pass any valid phoenix expression? Not just a simple operator
> expression, but an if/else, while, or an expression made of several
> statements?
> I want an arbitrary phoenix expression.
> That I need a decltype is clear and what I'm already doing. But an
> expression containing references, pointers, or even an int would be of
> no use for a decltype.

Yes, this is a problem. I don't know how this can be solved without actually 
passing the expression.

> >> std::transform(vec.begin(),vec.end(),vec.begin(), ++_1 + foo_(_1) );
> >
> >To answer your question, phoenix actors return their last statement. In
> >your case the result of ++_1 + foo_(_1) is returned.
> 
> Hmmm now I'm lost. Just after you write that if_/else_ returns nothing.

See below.

> >> std::transform(vec.begin(),vec.end(),vec.begin(),
> >> if_(_1)[ ++_1,return_(++_1)].else_ [return_(++_1)] );
> >
> >Ok, if_(...)[...] and if(...)[...].else_[...] are statements in phoenix,
> >meaning they return nothing (aka void). The answer to your question is
> >to simply use phoenix::if_else which is in the operator module because
> >it emulates the ?: operator.
> 
> Ok but this is just a partial answer, right? What about while / do or
> whatever I might need?
> I would like a clear statement: If I have an expression composed of
> any number of statements of any type and any order inside the full
> extent of phoenix (say if_().else_[], while_(), ++_1,fun_()), what is
> the return value?
>
> From what you write I understand "the last statement except in some
> cases". Which ones?

Calling phoenix expressions from the statement module return void.
Calling phoenix expressions from any other modules return whatever ... 
depending on the "C++-Sense".
You might ask for example:
What does _1 + _2 return?

The answer is: It returns a callable expressions. When the expression gets 
called with two arguments that call will return the result of the addition, 
or however operator+ is overloaded for the types passed ...

In Phoenix you also have the overloaded operator, - which emulates 
sequences.
Now there is no return statement in phoenix. A call to a phoenix expression 
will return whatever expression (now talking in the C++ sense) the last 
expression was, where a phoenix expression can be composed and is maybe 
arbitrary complex.
This can be void or something totally different.

There are only some cases where the return value is fixed to a certain type.
In particular everything from the "Statement" module was defined to return 
void to match the C++ semantics.

> >As Eric already noted, Phoenix captures everything by value. There is no
> >special syntax needed to capture other variables in scope (if you want
> >to capture them by value, meaning that they will get copied into the
> >phoenix expression). Your solution is similar to what is there in
> >phoenix already: Local variables and the let/lambda expressions. Your
> >examples will have your exact "better syntax":
> >
> >lambda[ _a = q ] [ _1 + _a /* first"captured" */]
> >
> >lambda[ _a = ref(q) ] [ _a++ /* first "captured" */ ]
> >
> >lambda[ _a = cref(q) ] [ _1 + _a /* first "captured" */ ]
> 
> Ah perfect! This is what I'm looking for.
> 
> >> Ok, these ones I didn't implement them, but I can dream.
> >
> >I am dreaming with you! :)
> 
> Let's not dream much longer then ;-)
> We have here people who can do it.
> 
> >By looking at these examples i can not see what's there that is not
> >provided by Phoenix already.
> 
> Then it's perfect and what I want, but I'll need to give it a closer
> look. Mostly I want:
> - return values
> - the ability to decltype anything. For MSM it's about the same as the
> std::set case.
> 
> If you allow a short criticism, I'd say that phoenix is great and
> maybe even offers all I want, but the doc is doing it a great
> disservice. I got so frustrated I started my own implementation and
> seeing my lack of time, it means something ;-)

Maybe you should have asked before you started re-implementing everything ;)

> What I think we need is:
> - more different examples showing what it can do, not the trivial
> examples it currently took over from V2

Phoenix comes with a who

Re: [proto] My own lambda for MSM / wish list

2011-03-14 Thread Thomas Heller
On Sunday, March 13, 2011 10:07:30 PM Christophe Henry wrote:
> Hi all,
> 
> I started a rewrite of a major part of my eUML front-end to fix the
> issues I left open in the current version, and I'm now at the point
> where I've done enough to present what I have and get some opinions on
> the choice I'm facing: continue or switch to phoenix. I remember
> discussing the subject at the last BoostCon and it looked like my
> whishes were not possible, but it was almost one year ago, so I might
> not be up-to-date.
> 
> I admit I'm having a lot of fun implementing this stuff. It's great to
> play with proto :)
> 
> I wanted to start a discussion on this list to get some feedback (and
> fresh ideas) from much more knowledgeable proto experts, so here are
> some thoughts.
> 
> Phoenix is a great library, but I did not find all I was looking for,
> so here is what I'm still missing. I provide an implementation to
> illustrate my wishes.
> 
> 1. Creation of a default-constructible functor for MSM
> 
> This one is my N°1 requirement. I started this stuff for MSM.
> MSM is based on transition tables, each transition being something like:
> 
> Row  < source_state , event ,  target_state, action , guard  >

I suggest you to look into spirit how semantic actions are dealt with, it 
reminds me of exactly this:

> With action and guard being a functor, say:
> struct guard{
> template 
> bool operator()(Evt const&, Fsm&, SourceState&,TargetState& )
> {
> ...
> }
> };
> 
> Which MSM then calls, for example: return guard()(evt,fsm,src,tgt);
> Note that I need a default-constructible functor whose type can be
> saved as a template argument.

Phoenix actors are POD, they are default constractible. Do you have a 
testcase where this is not the case?

> MSM also offers a "FP" collection of classes to build functors on the
> fly. For example, if I want a more complicated guard, I can write:
> And_< Or_, Not_ >
> 
> eUML builds on top of this so that I can write: (g1 || g2) && !g3 .
> To achieve this, I use a typeof call of a proto expression for all
> these operators. So it's kind of a compile-time proto grammar,
> generating the above "Row".
> This is already implemented (not very well) in eUML, so I know it
> works but needs improvements.
> 
> 2. STL, type definition
> 
> Ideally, as I'm at it, I want to avoid writing functors for use in the
> STL, which is phoenix stuff. But reading the doc I didn't manage to
> find out if I can write something close to:
> std::set s;
> 
> The re-implementation I'm working on is coming close enough for my taste:
> std::set s2;

As Eric noted, decltype is the answer. I can't see why this should not be 
possible within phoenix.

> 3. STL, algorithms
> 
> I found in phoenix's doc many examples with for_each but not many with
> others like transform, which require something to be returned from a
> lambda expression.
> I want:
> std::transform(vec.begin(),vec.end(),vec.begin(), ++_1 + foo_(_1) );

To answer your question, phoenix actors return their last statement. In your 
case the result of ++_1 + foo_(_1) is returned.

> Ideally, I'd also be able to write:
> 
> std::transform(vec.begin(),vec.end(),vec.begin(),
> if_(_1)[ ++_1,return_(++_1)].else_ [return_(++_1)]  );

Ok, if_(...)[...] and if(...)[...].else_[...] are statements in phoenix, 
meaning they return nothing (aka void).
The answer to your question is to simply use phoenix::if_else which is in 
the operator module because it emulates the ?: operator.

> Ok, I didn't succeed yet, but I manage:
> 
> std::transform(vec.begin(),vec.end(),vec.begin(),
> lambda[ if_(_1)[ ++_1, /* return */++_1 ] /*else */  [ ++_1 ]
>  ] );

This is another solution to your problem, yes

> 
> Where there is a kind of implicit return and where ";" is replaced by ","
> : ++_1; return_ (++_1)  => ++_1 , ++_1 /* second ++_1 is returned */
> 
> 
> 4. A taste of C++0x lambda: capturing
> 
> One thing which is bugging me with phoenix is the ref / cref adding
> noise to my nice FP (I'm kind of a new convert). I prefer the C++0x
> solution of "capturing", which looks to me like an extended function
> declaration. For example:
> [x, y](int n) { ...}
> Or:
> [&x, &y](int n) { ... }
> 
> I don't despair to achieve a similar syntax, but for the moment I have
> only: lambda[ /* capture */_capture << q <<... ] [ _1 + _c1 /* first
> "captured" */ ] Or:
> lambda[_capture << ref(q) ] [ _c1++ /* first "captured" */ ]
> Or:
> lambda[_capture << cref(q) ] [ _1 + _c1 /* first "captured" */ ]
> 
> I think a better syntax would be lambda[_c1=q, _c2=4][...]

As Eric already noted, Phoenix captures everything by value. There is no 
special syntax needed to capture other variables in scope (if you want to 
capture them by value, meaning that they will get copied into the phoenix 
expression).
Your solution is similar to what is there in phoenix already: Local 
variables and the let/lambda expressions. Your examples will have your exact 

Re: [proto] My own lambda for MSM / wish list

2011-03-13 Thread Joel Falcou

On 14/03/11 04:49, Eric Niebler wrote:

Exciting stuff! Truly Christophe, your ideas re decltype and EDSLs in
C++ are revolutionary. But unfortunately, I fear it will require a
revolution. This is all do-able, but the changes to MPL, Proto and even
to Phoenix in the case of the lambda capture stuff would require
breaking API changes.


The main problem is that we still segregate type operations from  their 
runtime counterpart,

this leads me to ...


As for MPL and Proto, someone needs to sit down and do some hard
thinking about what meta-programming will look like in C++0x. I suspect
it'll look less like today's MPL and Proto, and much more like what you
envision. It's a huge opportunity for someone to do some really
ground-breaking work.



.. the talk from Matt Calabrese last year at boostcon with the 
MPL/Fusion hybrid
using decltype and auto. I think this is an interesting venture all in 
all and should

be extended.

I have the same kind of ideas Christophe plus a few other (including a 
real meta-DAG structure).

Maybe we should get Matt in our boat and try hammering stuff ?
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] My own lambda for MSM / wish list

2011-03-13 Thread Eric Niebler
Hi Christophe,

First let me say that I have limited bandwidth at the moment, and
apologize in advance for my short reply...

On 3/14/2011 4:07 AM, Christophe Henry wrote:
> Hi all,
> 
> I started a rewrite of a major part of my eUML front-end to fix the
> issues I left open in the current version, and I'm now at the point
> where I've done enough to present what I have and get some opinions on
> the choice I'm facing: continue or switch to phoenix. I remember
> discussing the subject at the last BoostCon and it looked like my
> whishes were not possible, but it was almost one year ago, so I might
> not be up-to-date.
> 
> I admit I'm having a lot of fun implementing this stuff. It's great to
> play with proto :)
> 
> I wanted to start a discussion on this list to get some feedback (and
> fresh ideas) from much more knowledgeable proto experts, so here are
> some thoughts.
> 
> Phoenix is a great library, but I did not find all I was looking for,
> so here is what I'm still missing. I provide an implementation to
> illustrate my wishes.
> 
> 1. Creation of a default-constructible functor for MSM
> 
> This one is my N°1 requirement. I started this stuff for MSM.
> MSM is based on transition tables, each transition being something like:
> 
> Row  < source_state , event ,  target_state, action , guard  >
> 
> With action and guard being a functor, say:
> struct guard{
> template 
> bool operator()(Evt const&, Fsm&, SourceState&,TargetState& )
> {
> ...
> }
> };
> 
> Which MSM then calls, for example: return guard()(evt,fsm,src,tgt);
> Note that I need a default-constructible functor whose type can be
> saved as a template argument.
> 
> MSM also offers a "FP" collection of classes to build functors on the
> fly. For example, if I want a more complicated guard, I can write:
> And_< Or_, Not_ >
> 
> eUML builds on top of this so that I can write: (g1 || g2) && !g3 .
> To achieve this, I use a typeof call of a proto expression for all
> these operators. So it's kind of a compile-time proto grammar,
> generating the above "Row".
> This is already implemented (not very well) in eUML, so I know it
> works but needs improvements.

And what you need is for the type of the Proto expression generated by
"(g1 || g2) && !g3" to be default-constructable? Have you tried doing
this with an expression adaptor and a domain in which child nodes are
all held by value (because reference members cannot be
default-constructed)? What errors did you run into?

> 2. STL, type definition
> 
> Ideally, as I'm at it, I want to avoid writing functors for use in the
> STL, which is phoenix stuff. But reading the doc I didn't manage to
> find out if I can write something close to:
> std::set s;

I don't see how that could ever work. Any way you slice it, (_1 < _2) is
an expression, not a type. decltype(_1 < _2) could be made to work, for
some suitably defined _1, _2, and <. And yes, (_1 < _2) would need to be
default-constructable.

> The re-implementation I'm working on is coming close enough for my taste:
> std::set s2;

Yeah.

> 3. STL, algorithms
> 
> I found in phoenix's doc many examples with for_each but not many with
> others like transform, which require something to be returned from a
> lambda expression.
> I want:
> std::transform(vec.begin(),vec.end(),vec.begin(), ++_1 + foo_(_1) );
> 
> Ideally, I'd also be able to write:
> 
> std::transform(vec.begin(),vec.end(),vec.begin(),
> if_(_1)[ ++_1,return_(++_1)].else_ [return_(++_1)]  );

This just looks like Phoenix. Why can't you use it directly?

> Ok, I didn't succeed yet, but I manage:
> 
> std::transform(vec.begin(),vec.end(),vec.begin(),
> lambda[ if_(_1)[ ++_1, /* return */++_1 ] /*else */  [ ++_1 ]  ] 
> );
> 
> Where there is a kind of implicit return and where ";" is replaced by "," :
> ++_1; return_ (++_1)  => ++_1 , ++_1 /* second ++_1 is returned */
> 
> 
> 4. A taste of C++0x lambda: capturing
> 
> One thing which is bugging me with phoenix is the ref / cref adding
> noise to my nice FP (I'm kind of a new convert). I prefer the C++0x
> solution of "capturing", which looks to me like an extended function
> declaration. For example:
> [x, y](int n) { ...}
> Or:
> [&x, &y](int n) { ... }
> 
> I don't despair to achieve a similar syntax, but for the moment I have only:
> lambda[ /* capture */_capture << q <<... ] [ _1 + _c1 /* first "captured" */ ]
> Or:
> lambda[_capture << ref(q) ] [ _c1++ /* first "captured" */ ]
> Or:
> lambda[_capture << cref(q) ] [ _1 + _c1 /* first "captured" */ ]
> 
> I think a better syntax would be lambda[_c1=q, _c2=4][...]

Ah, yeah. There was discussion during the early design phases about
capturing. It can't be done without (a) a "lambda" introducer like you
have, and (b) by-ref terminal capture by default by the DSEL. Phoenix
zigged, and you seem to be wishing we'd zagged. There's no going back
now. Phoenix captures terminals by value.

> 5. More compile-time DSLs, more!
> 
> So, am I final