Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2002-01-24 12:19:09


> From: Karl Nelson [SMTP:kenelson_at_[hidden]]
> >
> > > > Try deviating from the printf-like notation in the format string since
> this
> > > > isn't allowing for any printf-like functionality:
> > > >
> > > > format("[3], [1] [2]-th try")[40.23](hex)[50]["toto"];
> >
> > This format statement is rediculously overblown. I have enough problems
> > with overloading the modulus operator to something non-directional.
> > making [] take non-integer arguments seems totally out of place.
>
> Are you familiar with std::map? It offers the subscript operator as a way
> of accessing elements, and the keys need not be integers. Consequently,
> there is precedence for non-integer arguments between "[" and "]".

Sorry. I should say "non-indexing" arguments.
I don't really see how format()[][][][] looks like indexing.

 
> > Can we stick to just the format with operator <<, format with operator
> > %, and format with variable arguments for the discussion?
>
> No, but we can discuss that, too.

  Those three are the three we had on the table before the
review. So currently we are debating no less than 4 mutually
exclusive uses of format.

    format(cout, "%1$s %2$x") << 1 << 2;
    cout << format("%1 %p2$x") % 1 % 2;
    cout << format("%1 %2", 1, hex, 2);
    cout << format("[1] [2]")[1](hex)[2];

I would argue that most of these are grossly misnamed. We are really
trying to discuss "formatting" but the library for review mixes reorder
and format in the same context. They may share implementation details
but they are reasonably unique concepts. (format includes reordering and
format specifiers.)

 
> > I still think that it is not unrealistic to simply write
> >
> > format(cout,"%3$s, %1$s %2$s-th try") << 40.23 << hex << 50 << "toto" ;
> >
> > It looks like a stream and it is compact.
>
> I'm not the least bit familiar with Unix98 printf() format specifiers, so I
> don't know what that format means. (I purposely skipped that part of the
> documentation, because printf() compatibility is not important to me.)

Unfortunately, that is really part of the heart of the problem here.
I proposed a library originally for a very narrow purpose which was to
support the internationization of C++ with gettext.

  cout << format(gettext("My name is %s and my age is %d")) << 1 << 2 <<endf;

Where gettext is a C library i18n tool and thus strict unix98 printf
format is required. (You can not tell from which linked object in a
mixed project a string may have come, especially when you aren't the
one doing the translation.) It must do reordering and must have the
the formatters in the stream to account for things like different
numbers of digits and widths in other languages.

This submission mutated into another submission which combined another
misnamed format (really reorder) operator. That is what is under review.
However, I think the reviewed library missed on multiple fronts.
It mixed the terms format hopelessly and didn't take strict
printf as they wanted to support the reordering as the first function.
Those are the reasons I would have for rejecting it. (add my petty
concern that it should use << to be familar).

However, rejection on the basis of "we don't think printf is needed" means
completely throwing out the whole purpose of my submission in the
first place!

> I'm
> going to guess that the printf() % specifiers can have an embedded
> positional indicator which is a number followed by $. Given that, and
> assuming that format complains at compile time when %s isn't given a string

Under C++ the %s means "literal string". Thus placing any unspecified
text through it is acceptable.
 
> as shown in your example, I still have one problem: I can't tell whether
> "hex" is a variable in scope at this point, or whether it std::hex brought
> into scope via some IOStreams header. That may not be a likely point of
> confusion for "hex," but my point is that you can't tell that 50 is argument
> 2, not 3.

Well hex was a bit unnecessary in that example. All manipulators are
non-sticky in my implementation. About the only manipulator which is
really often needed is width...

   format("%8s %x") << 1 << width(q) << 2;

   %8s - means string

Where q is a variable and not known at run time.

As to where the manip came from doesn't matter. You can force a "foriegn"
manipulator into service under the reviewed library with

   format("%1 %2") % 1 % manip(std::hex) % 2;

(I am submitting a boost::iomanip for removing that limitation)

> > > By the way, Robert's approach doesn't mention about how to write
> brackets.
> > > Maybe we can have "%[" be a literal open square bracket, "%]" be a
> literal
> > > close square bracket, and "%%" be a literal percent.
> >
> > Why must we confuse the user with dozens of new concepts like the above?
> > Printf format is well defined and widely used. Besides in an mixed
> > code you would not want to send format strings with mixed formats.
> > This point has been discussed many times over. If we are going to
> > have a "formatted printing" it should be "formatted". If you
> > want to resubmit a "reorder" manipulator for C++ streams it
> > may be appropraite, but it does not negate the need for a
> > formatted printing operator.
>
> Indeed, the point I made was to split the two.

Agree. The question is then one of "namespace". Competing
"reorder" implementations should use what name, and competing
"format" (reorder AND compact format specifications toward printf
like functionality) should use what name?

--Karl


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