Boost logo

Boost :

From: Craig Tiller (ctiller_at_[hidden])
Date: 2002-02-25 05:20:34


Just posted the nucleus of this idea to comp.std.c++, but had some more
thoughts,
so I thought I might solidify the idea here (shrugs)

*IF* we had templatized typedefs, couldn't we also do something like

template <class T> T integer = lexme[ !(ch_p('+')|'-') >> +digit ]; //
compiler deduces T

and if that was the case, then typedefs should probably have the same
semantics, so I could write

typedef <class T> T deduced;
and then

deduced integer = lexme[ !(ch_p('+')|'-') >> +digit ];

in its full generality then, it means that if you write a template type as
the LHS of an expression, its template parameters get deduced as a functions
would, or thereabouts (so the same thing should work if you had a class...
see below)

what this means is that you could get more specific if you wanted to, so you
could allow more information
in your source (which is usually a good thing...); say...

template <class T> class SpritRule; // defines common stuff for each rule
type T for the spirit parser
SpiritRule match_integer = lexme[ !(ch_p('+')|'-') >> +digit ];

I'd love to hear what others think... but to me it just feels so right :)

----- Original Message -----
From: "joel de guzman" <djowel_at_[hidden]>
To: <boost_at_[hidden]>
Cc: "Spirit-general" <spirit-general_at_[hidden]>
Sent: Saturday, February 23, 2002 4:08 AM
Subject: Re: [boost] Keeping C++ feature discussion on topic for Boost

>
> ----- Original Message -----
> From: "Douglas Gregor" :
>
> > On Friday 22 February 2002 08:04 am, you wrote:
> > > I have to disagree with this. 'auto' is a nice feature that definitely
gets
> > > publicity but it's _not_ needed for writing libraries (except for the
> > > return type autodeduction which is solved by typeof.)
> >
> > I would put auto in the 'needed for writing libraries' category because
it
> > allows libraries to be moved further into the metaprogramming domain. My
best
> > example here is the Spirit parser. The only reason that Spirit parsers
are a
> > bit pokey now is because we have to declare a type for a Spirit rule, as
in
> > the following grammar:
> >
> > rule<> integer;
> > rule<> group;
> > rule<> expr1;
> > rule<> expr2;
> > rule<> expr;
> > integer = lexeme[ !(ch_p('+') | '-') >> +digit ];
> > group = '(' >> expr >> ')';
> > expr1 = integer | group;
> > expr2 = expr1 >> *(('*' >> expr1) | ('/' >> expr1));
> > expr = expr2 >> *(('+' >> expr2) | ('-' >> expr2));
> >
> > However, if we had 'auto', Spirit could put _everything_ in a giant
> > expression template, and therefore not require the expensive
redirections
> > through virtual functions that it does now. I'm going to invent a little
> > syntax here to make this work, but essentially we could have:
> >
> > struct Expr {};
> > auto integer = lexeme[ !(ch_p('+') | '-') >> +digit ];
> > auto group = '(' >> rule<Expr>() >> ')';
> > auto expr1 = integer | group;
> > auto expr2 = expr1 >> *(('*' >> expr1) | ('/' >> expr1));
> > auto expr = rulename<Expr>(expr2 >> *(('+' >> expr2) | ('-' >>
expr2)));
> >
> > The rule<Foo>() construct references a rule that has not yet been
defined but
> > will have the static name 'Foo'. rulename<Foo>(my_rule) gives 'my_rule'
the
> > static name 'Foo'. This allows recursion statically.
> >
> > The overall result: this entire grammar can be stored as an expression
> > template, and with a little nifty metaprogramming Spirit can produce
very
> > efficient parsers for static (parts of) languages.
>
> Indeed. I wish I could be as eloquent as Doug. The Spirit inline parser
> is a case where the auto keyword will boost its expressiveness **and**
> performance a lot. The typeof(x) will only address the performance issue.
> For instance here's the same calculator grammar above written using
typeofs:
>
> struct Expr {};
> typeof(lexeme[ !(ch_p('+') | '-') >> +digit ])
> integer = lexeme[ !(ch_p('+') | '-') >> +digit ];
> typeof('(' >> rule<Expr>() >> ')')
> group = '(' >> rule<Expr>() >> ')';
> typeof(integer | group)
> expr1 = integer | group;
> typeof(expr1 >> *(('*' >> expr1) | ('/' >> expr1)))
> expr2 = expr1 >> *(('*' >> expr1) | ('/' >> expr1));
> typeof(rulename<Expr>(expr2 >> *(('+' >> expr2) | ('-' >> expr2))))
> expr = rulename<Expr>(expr2 >> *(('+' >> expr2) | ('-' >> expr2)));
>
> Yuck!
>
> Without the auto keyword, I had to resort to virtual functions to
> encapsulate the RHS (much like what Doug has done with boost's
> function lib). Without it, and without typeof (as C++ currently is) the
> explicit type of the RHS will have to be typed. For instance:
>
> alternative<chlit<char>, chlit<char> >
> sign= ch_p('+') | '-';
>
> Now I can't imagine rewriting Hartmut's C parser this way.
>
> Bottom line is: expressiveness matters!
>
> Regards,
> --Joel
>
>
>
>
>
>
> Info: http://www.boost.org Send unsubscribe requests to:
<mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk