Boost logo

Boost :

Subject: Re: [boost] [local] Simplifying the parenthesized syntax
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2011-02-07 12:37:02

Lorenzo Caminiti wrote:
> On Sun, Feb 6, 2011 at 10:26 AM, Vicente Botet <vicente.botet_at_[hidden]>
> wrote:
>> The fact that you can not use variadic macros at work doesn't means that
>> your library can not provide in addition variadic macros on compilers
>> supporting them. I have no idea the work that this suppose, but if the
>> interface could be more appealing your library will have much more people
>> interested in.
>> Have you an idea of how the interface could be simplified if variadic
>> macros
>> were used?
> The purpose of this email if to brainstorm possible ideas to simplify
> the parenthesized syntax. Sorry in advance if not all that I say is
> correct -- I haven't implemented it yet so I might be saying
> inaccurate/unfeasible things here and there. As always, your feedback
> is very welcome :)
> Consider the following parenthesized syntax for local functions:
> (void) (f)( (int)(x) (double&)(y) (const bind)((a)(&b))
> (bind)((&c)(d)) ) // [0]
> The followings are possible ways to simply this syntax.
> Parameter names can be passed to function types so I can transform
> `int x` into `int` at compile-time:
> int x --[make function type]--> void (int x) --[get 1st parm type]-->
> int
> This should allow me to simplify the parenthesized syntax [0] to:
> (void) (f)( (int x) (double& y) (const bind)((a)(&b))
> (bind)((&c)(d)) ) // [1]
> Note that the (unbound) parameter type and name are merged into a
> single sequence element.
> The following should also be possible:
> (void) (f)( (int x) (double& y) (const bind a) (const bind& b)
> (bind& c) (bind d) ) // [1a]
> Is [1a] simpler than [1]? Maybe it is...

It is simpler for me.

> Using variadic macros I _might_ be able to use a variable length tuple
> (can I? I am not very familiar with these yet...) instead of a
> sequence to represent the function parameters:
> (void) (f)(int x, double& y, const bind a, const bind& b, bind& c,
> bind d) // [2]

Yeah. This is looking quite close to a C++ function signature. What do you
think of spiting the parameters part from the binding part

    (void) (f)(int x, double& y)(const bind a, const bind& b, bind& c, bind
d) // [2a]

> I think, this is a great simplification over [0] because it is the
> exact same syntax used by C++ to declare function parameters!
> Note that `const bind` and `bind` have been distributed to all the
> bound parameters. Given that sequences are best avoided here (to
> reduce extra parenthesis), I do not think there is a less verbose way
> to enumerate the bound parameters. The followings could also be
> possible:
> (void) (f)(int x, double& y, const bind (a, &b), bind (&c, d) ) // [3]
> (void) (f)(int x, double& y) (const bind)(a, &b) (bind)(&c, d) // [4]
> But I think enumerating every bound variable separately as in [2]
> makes the parameter list syntax look the closet to normal C++ syntax
> even if it requires the repetition of `const bind` and `bind` as the
> types of the bound variables. Therefore, I would prefer [2] over both
> [3] and [4].
I don't like [3]. [4] is close to my 2a proposition and is quite short. I
    (void) (f)(int x, double& y) (const bind a, const bind& b, bind& c, bind
d) // [2a]
    (void) (f)(int x, double& y) (const bind)(a, &b) (bind)(&c, d) // [4]

> 3 RETURN TYPE AND FUNCTION NAME (C++ and C99 preprocessors)
> I don't know how/if I can simplify the passing of the return type and
> function name because I do need the function name as a separate token
> within the preprocessor to do token concatenation and generate unique
> names that refer to the function name...
> Something like this should be possible (using tuples instead of
> sequences):
> void, f, ( (int)(x) (double&)(y) (const bind)((a)(&b))
> (bind)((&c)(d)) ) // [5]
> void, (f)( (int)(x) (double&)(y) (const bind)((a)(&b))
> (bind)((&c)(d)) ) // [6]
> And again, on C99:
> void, f, (int x, double& y, const bind a, const bind& b, bind& c,
> bind d) // [7]
> void, (f)(int x, double& y, const bind a, const bind& b, bind& c,
> bind d) // [8]
> However, I don't see how these are simpler than [0] and [2]. I need to
> think about this more to see if other syntaxes are possible...

Using tuple instead of sequences, could [4]

    (void) (f)(int x, double& y) (const bind)(a, &b) (bind)(&c, d) // [4]


    void, f, (int x, double& y) (const bind a, &b) (bind)(&c, d) // [4a]


> 4 DEFAULT PARAMETER VALUES (C++ and C99 preprocessors)
> Currently local functions support default parameters via the following
> parenthesized syntax:
> (void) (f)( (int)(x)(default)(-1) (double)(y)(default)(1.23) ) // [9]
> I think this could be simplified to (note the removal of the
> parenthesis around the default value):
> (void) (f)( (int)(x)(default -1) (double)(y)(default 1.23) ) // [10]
> An additional simplification could be to merge parameter types and
> names together as in [1]:
> (void) (f)( (int x)(default -1) (double y)(default 1.23) ) // [10a]
> Plus using C99 variadics as in [2]:
> (void) (f)(int x, default -1, double y, default 1.23) // [11]
> I am not a big fan of this because `default` is separated from its
> parameter by the comma `,`... but I don't think I can do better than
> this.

Why you can not use the = symbol? Could this be

    (void) (f)(int x = -1, double y = 1.23) // [11a]

> These considerations are not directly relevant to local functions but
> the parenthesized syntax [0] was designed as a general syntax that
> makes *all* the elements of a function declaration available for
> preprocessor metaprogramming. Instead, syntaxes [1] and [2] cannot
> separate the parameter type token from the parameter name token at
> preprocessing time. Therefore:
> <snip>
> Therefore, *IF* there was an interest in defining the parenthesized
> syntax to be as general as possible so it could be adopted everywhere
> macros spoil function definitions (to avoid requiring programmers to
> learn different syntaxes for the different macros), [0] is more
> general because it separates the parameter types from their names (at
> the cost of the extra parenthesis of course).
> Of all of these syntaxes, I _personally_ like [0] because it is pure
> C++ preprocessor and it is the most general (maybe with simplification
> [10] for default parameters). I also would like to provide [2] if the
> C99 preprocessor is detected -- ideally, the same parsing macros will
> be smart enough to accept both [2] and [0] on C99 and just [0] on pure
> C++ preprocessors.

Lorenzo I understand your concern and that you need the general syntax for
Boost.Contract. Whether this general syntax is adapted to Boost.Local also
is what you are trying to analyze in this post.


View this message in context:
Sent from the Boost - Dev mailing list archive at

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