Boost logo

Boost :

From: Samuel Krempp (krempp_at_[hidden])
Date: 2002-01-30 19:00:13


On Wed, 2002-01-30 at 23:56, James Kanze wrote:
> The problem is that
>
> format( "..." ) % x * y % z ;
>
> is parsed wrong. Generally, this should result in a compiler error, but
> I would be very surprised if we can get away with not having format
> implicitly convert to std::string, which means that:
>
> format( "..." ) % x + y ;
>
> will NOT be a compile time error if x and y are strings.

yes it will, I've carefully insured it would.
there is no implicit conversion to string.
(when wondering what kinds of trouble this implicit conversion could
bring, I detected the problem with '+')

>
> IMHO, the best solution is just to forget about the operator (and the
> implicit conversions), but try selling that.

maybe I'm giving too much importance to appearance, but I'm not pleased
by lines like :
cout << format( fstr ).with( x1 ).with( x2 ).with( x3 );

when I can have, for the price of compile-time catched
user precedence errors :
cout << format( fstr ) % x1 % x2 % x3;

the repeated 'with' makes the statement very long, full of words, and
the eye can't catch what's happening, nor detect an output in the middle
of other lines of code.

In my view, that's (very generally) the benefit of operators : the lines
of code gain in readability.

Also very generally, the problem with operators, is that it can interact
with others, with rules that the user might not grasp, or might not be
able to apply safely 100% of the times.

But I thought it was OK as long as there is no implicit conversion
kicking in. Because, as long as we obey this constraint, precedence
mix-ups result in compile time errors.

format objects have no implicit conversions defined, and I believe the
precedence mix-ups due to operator% would all be detected at
compilation.

> It's true that the printf uses the format specifier for two things, the
> type, and how to format it. And obviously, a C++ implementation doesn't
> need the first. But is there an easier way than %f and %e to say that
> you want fixed or exponential format?

no, %e and %f do their job of specifying a float format nicely.
But what when you don't have a specific idea on this, and you just want
'default' formatting ?
What comes to mind, is use '%s' by default. e.g :
string path="010010";
double p = 0.0043;
format("Result : f(%s) == %s ") % path % p;

Problem is all the type-characters imply some actions,
even %s.
e.g., once you want to set precision, you might use :
format("Result : f(%.4s) == %.4s ") % path % p;
But no, crazy you ! precision, with %s, means truncation..
So '%s' is a very special type-char after all.

'%d' has less effect : it simply sets decimal base.
but... if the argument is passed with a 'hex' manipulator,
we've enforced decimal base but did not mean to.

So we need a new type-character, defined as doing nothing, just closing
the directive.
say, 'a' :
format("Result : f(%.4a) == %.4a ") % path % p;

at this stage, I realised I simply preferred importing printf syntax,
inside brackets, making the final type-character optional, rather than
using directly printf syntax, and require a type-char to end each
directive.
format("Result : f(%{.4}) == %{.4} ") % path % p;

it looks more natural, each directive is visually grouped (just like the
other proposed syntax, '[stuff]' ),
and we can omit the type-character if we don't need one.
We can also support "%1" at the same time.

and we still benefit from the conciseness of the printf syntax.

the "{stuff}" mechanism is completely intuitive, so no trouble to get
used to.

I'm writing documentation now, introducing clearly the choice
between pure printf and new syntax, and it seems to me this modified,
encapsulated printf is easy to grasp.

so I'll go with this one.

-- 
Samuel

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