Boost logo

Boost :

Subject: Re: [boost] Phoenix review
From: Doug Gregor (dgregor_at_[hidden])
Date: 2008-09-25 11:14:38

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

>> 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

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