Re: New compose and format API



Daniel Elstner wrote:
Am Dienstag, den 14.08.2007, 10:59 +0800 schrieb manphiz:
The compose and format API saves C++ from gettext a lot. And it reminds me a similar library of boost::format [1], which basically does the same thing, but provides different interfaces. I'm not an expert, but I believe the Boost one might be better than yours in the following 2 aspects:

Thanks a lot for your feedback.  I just had a look at the boost format
API.  It's actually quite similar to my proposal despite the apparent
differences.  Let's see:

1. format-string specification

boost::format retains the old printf format (%spec), and provides more flexible syntax, such as %|spec| which can omit the type-conversion character, as well as %N% which plays as place holder, while you were using %N as place holder. The lack of printf-like format might results in incompatible interfaces with plain printf and might compromises the interoperability of format string with other printf-like functions. Though they are definitely not good choices, they are still widely used. However, you can implement the same thing of course :)

Interesting.  Apparently boost allows printf syntax to control output
formatting while ignoring the implied type information, since the latter
is determined at compile time.  Nice idea but probably overkill, as it
also supports I/O manipulators.  Although supporting both would allow
the programmer to yield control over the format to the translator.  Are
there valid use-cases for this?  Generally it's cleaner to only allow
reordering.

With regards to interoperability with printf I don't see the problem,
except perhaps for a lack of familiarity with the format on the part of
the translators.  However, the syntax is extremely simple and intuitive,
and any mistakes should hopefully be caught by msgfmt when run with the
"--qt" option.  As it happens I'm already using this syntax in regexxer
and there has been only one accidental mistranslation as far as I can
remember.

I agree, at least we still have printf, and ustring::compose()'s primary concern is to ease the case. Now it becomes merely a taste of syntax.

2. operater%

Boost uses operator% to concatenate different part, which is generally type safer than variadic function calls, and might provides more flexibility in implementation before C++ allows overloading operator,.

Actually the current API doesn't use variadic functions but simply a set
of overloads of ustring::compose() to support up to nine arguments.

Well, fixed number of arguments is still a restriction after all, and IMHO variadic function might help better in this case. It reminds me for the case of boost::tuple, whose implementation is very complicated and verbose since it was implemented when there was no variadic template arguments and function template default arguments, which are added into C++0x now partly because of these issues.

Conceptually there isn't much of a difference between the two APIs:

  s1 = ustring::compose("%1 is lower than %2.", "12", "34")

  s2 = boost::format("%1 is lower than %2.") % "12" % "34"

Granted, with non-string arguments it gets uglier:

  s1 = ustring::compose("%1 is lower than %2.", ustring::format(12),
                                                ustring::format(34))

  s2 = boost::format("%1 is lower than %2.") % 12 % 34

Interestingly, boost introduces a group() function to avoid the
ambiguity that arises when I/O manipulators are used.  group() is
actually very similar to ustring::format(), except that it can be
omitted if no grouping is necessary.  So it seems there are now three
API variations to choose from:

  // 1) status quo
  s1 = ustring::compose("%1 is lower than %2.",
                        ustring::format(12),
                        ustring::format(std::setprecision(1), 34.5))

  // 2) boost-ish
  s2 = ustring::format("%1 is lower than %2.")
                       % 12 % group(std::setprecision(1), 34.5)

  // 3) half-breed
  s3 = ustring::format("%1 is lower than %2.",
                       12, group(std::setprecision(1), 34.5))

Hm, now that I think of it I actually like options 2) and 3) better than
my original proposal.  Implementing 3) should be fairly straightforward
but 2) might require some additional bloat.  I'll have to give it a try
to be sure though.

Have your say: Which would you prefer?

Operator% is somewhat weird at a first glance, but gains the power of type safety; and function calls is more familiar together with the inevitable trade off. Well, since it could be implemented in either way, it's now becoming a question of personal taste.

As a protagonist of Boost, I know my answer cannot be unbiased, so I won't do it :) It's up to you after all, and it can be left for more users to discuss.


Moreover - I think its less important - that boost::format has already been used for a while. Providing a similar syntax will of course increase the interoperability with many existing code using boost::format as well.

Worthwhile to consider, although I'm not convinced that we should adopt
boost's placeholder syntax.


Since neither is in C++ standard, it's not as strong as the other two as I said, but still worth evaluation. Interoperability is still a big concern, at least for me :)

Again, I'm not an expert, and I've no rights to judge anything, and your library has been written out for quite some time already. But I wish you may consider my proposal, and thanks for your effort :)

Your valuable input is greatly appreciated.


Thanks.

Btw, from a big picture, I think the compose and format stuff might be implemented outside of a particular string class, which will make them useful for std::string as well. And, according to the C/C++ standard committee documents, there are proposals to provide unicode character type(UTF-{8,16,32}) for C/C++, which might then eliminated the requirement of gchar/guchar or Glib::ustring or any transitional UTF-8 solution, though it won't be something happening very soon. Being implemented as separate algorithm, it might adapt any string types from the old ones to the new ones, just as flexible as boost::format.

Thanks,
--Daniel




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]