Boost logo

Boost :

Subject: Re: [boost] Phoenix review
From: Powell, Gary (powellg_at_[hidden])
Date: 2008-09-25 19:17:52

I vote to accept Phoenix into boost. It nearly duplicates nearly all of boost::lambda which I think is a good thing, and extends it (containers In some ways I'll miss the old name but it's time to move on. (And I like the imagery of an older system burning and becoming new again.)

On the code:
With all of the changes coming in C++0X, this isn't the last round of changes. I'm hopeful that with a fully compiant C++0X compiler Phoenix VX will be clear to even a casual observer. :> And with Proto it's likely that this won't be such a difficult task as it was the first time.

On syntax:
Things like case<constexpr>() [statement] the only alternative is to put the statement in the "()", and I prefer the current style with "[]". It fits with for_, while_ etc. Missing the "()" will make for nasty error messages but it can't be helped.

On boost::bind:
I'm in agreement with Doug, it will be a while before that library can be combined with this one. (years)

On Evaluation:
Documentation only. I've looked in depth at Phoenix before and it was cleanly written.

On Knowledge in problem Domain:
Well Peter Higgley and I wrote an early lambda FP paper in 2000 for C++ Report. Jaakko and I wrote the first generation of Lambda & paper soon after. (Jaakko has been the sole maintainer since and generated the boost quality version, including documentation.) Thanks Jaakko!



-----Original Message-----
From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]] On Behalf Of Doug Gregor
Sent: Thursday, September 25, 2008 8:15 AM
To: boost_at_[hidden]
Subject: Re: [boost] Phoenix review

On Sep 25, 2008, at 9:32 AM, Joel de Guzman wrote:

> Doug Gregor wrote:
>> The alternatively, of course, is to use a syntax like:
>> case_<1>()[cout << val("one") << '\n', cerr << val("hello")],
>> Interestingly, catch_<exception_type>()[ ... ] uses this same syntax;
>> why the discrepancy between case_ and catch_? Or did I miss
>> something?
> Yeah, the discrepancy... It's one of the things I'm not quite
> satisfied with. I do like the brackets [] but the empty parens stick
> out like a sore thumb to me. At one point, I used the [] for the
> cases, changing it later to the (). Fickle, ain't I?
> I'm open to suggestion. If we are to break the interface anyway, I'd
> follow what the community wants.

Personally, I don't find the extra ()'s in case_<1>() all that horrible, and I think it's the more regular to have all of the statements in []. That said, unless something *else* is breaking the interface, this isn't the thing that should be first to break the interface.

>> Anyway, now you have me trying to figure out how to tweak switch() to
>> fully support break_() and fall-through from one case to another :)
> Oh, that one! It's a tricky one to crack. Not much priority was given
> on that since no one really asks for it. To be honest, in terms of
> usability, I'd rather crack return_. I know it's doable, but it's
> always been a balance. I tend to shy away if the metaprogramming is
> getting quite involved. Not that I don't like the challenge. It's just
> that I want to tame down the compile times.

I'm not sure it's generally useful, but it sounds like a fun metaprogramming challenge :)

>> In the "Visibility" section, there's this example:
>> let(_a = 1)
>> [
>> let(
>> _a = 1
>> , _b = _a // Ok. _a refers to the outer _a
>> )
>> [
>> /*. body .*/
>> ]
>> ]
>> Personally, I would like to see this example be ill-formed. I know
>> it isn't technically feasible to make bind the "_a" in "_b = _a" to
>> the innermost _a, so instead I'd prefer if any use of a variable
>> whose binding has changed within the same "let" would be an error.
>> I *think* this can be done without too much pain through a static
>> assertion, but feel free to ignore this suggestion if I'm wrong.
> Hmmm. Ok duly noted. Let me look into this. Yes, I think a static
> assertion can be easily done.

Assuming it's not a compile-time killer, of course.

>> What level of interoperability can we expect among Boost.Bind,
>> Phoenix, Boost.Lambda, and TR1/C++0x's bind, if any?
> First should be the unification of the placeholders. I hate it when
> I have to use different placeholders for different libraries when
> they are essentially doing the same thing. The proto port is a good
> step in that direction.

Yes, this is very important for usability.

> Beyond that, I'd like to hear from you and the community what you
> want to expect. It's an open road. Phoenix has already done it's
> job as a Spirit sidekick. It's just now that it's actively venturing
> outside that sphere. I would love to have you and the community
> plot its future.

Well, I think Phoenix is the next-gen library to replace Boost.Lambda.
It's not that Lambda is bad---it's quite solid code---but we've
learned a lot about how to build FP libraries in C++, and I'm sure
that Jaakko would love to be free of the maintenance burden :) So, my
first suggestion would be to deprecate Lambda in the first Boost
release where Phoenix is available, and remove it one or two releases

Bind is trickier. Phoenix does cover all of Bind's functionality (as
far as I can tell), but Bind current works on horribly broken
compilers where Phoenix just won't go (and shouldn't). Bind is also
extremely lightweight from a compile-time perspective, while Phoenix
isn't quite so small. Perhaps Peter has a different opinion on this,
but I think Bind and Phoenix will coexist in Boost for a very long
time (and that's okay).

        - Doug
Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at