Boost logo

Boost :

From: James Kanze (kanze_at_[hidden])
Date: 2002-01-30 17:15:51


Samuel Krempp <krempp_at_[hidden]> writes:

|> On Sun, 2002-01-27 at 17:43, James Kanze wrote:
|> > First, of course, '%' is out of the question, since it has the
|> > wrong priority.

|> And in another message :
|> > As it is, % simply doesn't work because of the precedence

|> I don't agree with you.. it works. and it has worked for python
|> too, for years.

I'm not familiar with Python, but I have participated in many
discussions concerning adding operators (power, for example) to C++, and
the first requirement is always that the precedence allow the operator
to be used "naturally".

Let's face it, even << is a hack, and a horrible misuse of operator
overloading. We get away with it because of the precedence, the fact
that it is little used, and the suggestiveness of its graphic
presentation.

|> You reject operator% because its precedence is higher than that of
|> +/- ?

And the same as * and /.

|> If a user makes a mistake, like
|> format(format_string) % 1+2 ;
|> it's catched at compile-time.

|> It's the same in python, and it never was that much of a problem for
|> users.
|> Python 2.1.1+ (#1, Jan 8 2002, 00:37:12)
|> >>> print("%d") % 1+3
|> Traceback (most recent call last):
|> File "<stdin>", line 1, in ?
|> TypeError: cannot add type "int" to string

I can't say for Python, but it looks horrible. What I can say is that
Python isn't C++; not knowing the rest of Python, I can't say what there
is about Python which makes it work.

|> I believe users are able to notice that with '%', + and - oeprations
|> are to be placed into parentheses. If they don't notice it at
|> first, the compiler tells them, and then they'll know it.

All of which doesn't make it any more natural. Why make things overly
difficult for the user?

|> Needing parentheses for + and - may be a small inconvenience, but I
|> don't see that as a decisive argument at all.

If there were no other choices, I guess we could argue the point.

|> > If an operator is wanted, what's wrong with
|> > <<; it is currently the formatting operator, so why change it.

|> That's the real argument. You don't want '%' because you want '<<',
|> which precedence is a little bit different, and as a result you
|> blame '%' for not having the same precedence.

Actually, what I want is to forget this horrible misuse of operator
overloading completely. The most natural and readable way to write it
is:

    format( fmtString ).with( arg1 ).with( arg2 )

This is the way I normally use my own format class. But some people
seem to insist that it work like iostream, and want the operator<<. And
originally, I needed an operator (or a free function of some kind),
because the function must be a template, in order to leverage off of
existing operator<< -- you can't really ask for users to provide yet
another conversion function, and expect anybody to use your class. My
initial code used operator,(), which is really the only operator which
has the right precedence. On the other hand, overloading operator,() is
really a little too subtle for most programmers, so I decided to stick
with the known.

|> I preferred changing it, because passing arguments to a format
|> object is not exactly like passing them to a stream, I don't think
|> we should make it look the same.

That was my motivation behind using operator,(). All I can say is that
from practice, operator<< doesn't cause problems.

|> this was already stated,
|> cout << format("%1$d %2$d") << x ;
|> cout << y;

|> This is the most obvious sign that the format object is not behaving
|> like a stream-modifier.
|> There are other, subtler possible traps for users who are fooled by the
|> similarity with stream's '<<'.
|> One thing I don't like at all, is what happens once you are done with
|> the arguments for format, but want to continue using the stream.

That's the point that bothered me. I thought that most programmers
would try writing things like:

    cout << format( "%d %d" ) << arg1 << arg2 << endl ;

It didn't turn out that way in practice.

|> You wrote the following lines, in another message :

|> > |> It's a little easier to see the <<'s in the second statement
|> > |> than the %'s in the first. Unfortunately, using "<<"
|> > |> introduces problems interacting with streams,

|> > Is this from experience, or simply speculation? I was worried
|> > about the same thing in my format class, and hesitated for a long
|> > time (using operator,()). In the end, I bit the bullet, and in
|> > practice, it has never caused any problem. The one thing I did
|> > have to do at a customer site was recognize ostream manipulators,
|> > and use them to terminate the format, and shift back to outputting
|> > to the ostream. The rule sounds horrible and unorthagonal, but
|> > works well in practice, where people write things like:

|> > logfile << GB_Format( "..." ) << x << y << std::endl ;

|> Okay, so you have some overloads that make this things work, the
|> rules are horrible, but as long as the user doesn't try incredible
|> things, it works as he thinks it does.

I only tried this once. And because of the logfile, where the
programmer insisted on std::endl because he wanted the flush. I suspect
that if I'd have had the with() function at the time, I wouldn't have
done it then, since you could easily write:

    logfile << GB_Format( "..." ).with( x ).with( y ) << std::endl ;

Most of the time, the "logfile" is a separate type, which also uses
templates to leverage off existing operator<<, and the problem doesn't
existe.

But I would love to find an alternative operator (assuming we can't
forgo an operator completely), provided it had the right precedence.

|> Personnally, I prefer using '%', accepting the different precedence,
|> and desinging my format to have the simplest of behaviours,
|> independantly of what the user will want to do with the stream,
|> after using format.

|> In my opinion, the different precedence is nothing, compared to the
|> 'horrible rules' it saves us from.

|> And if indeed the choice is mine, I am going to keep '%' when
|> proposing the final library. I'll just have to hope it won't be
|> causing too many vetoes.. (I know now that I need to write more
|> arguments on that in the html)

I have no idea how boost voting works, or what effect it would have.
What I think is certain is that it would never be adopted as a standard
by the committee; I've been there, and I know the arguments.

-- 
James Kanze                                mailto:kanze_at_[hidden]
Conseils en informatique orientée objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

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