Poll on improved format strings.

Daniel Keep daniel.keep.lists at gmail.com
Tue Mar 6 23:46:12 PST 2007



renoX wrote:
> Hello,
> 
> I've made a templated format string templates joined in attachment (this new version is improved thanks to Frits van Bommel), but I'm not sure about the syntax of the format string.
> 
> The idea is: printf format string are interesting because they are powerful but they suck because the %d,%s, etc are in one part of the function and the corresponding variable are in a different part of the function (Tango has the same problem), writef improve this by allowing "... %d",var," ... %s",var2 but it's still not ideal because in the gluing of the various strings, it's easy to forget a space or a comma thus providing a not very good output.
> 
> So my idea would be to have embedded expression like this "... %08d{var1+var2} ...", but it's not easy to provide a good syntax/semantic, so I'd like some remarks:
> 
> -Should the mix of printf format and new style format string be allowed? (It is in the current implementation).
> This has the advantage of nearly keeping  the compatibility, the problem is with the format string "..%d{..." in printf this means a number followed by '{' but with the new format this creates an error.
> It is possible to escape the '{' to allow this, ie to say that '%{' is '{' so now '%d{' would need to be '%d%{', this has the inconvenient that it's not possible to have the embedding format '%{var}' which would be the shortest syntax..
> Another possibility would be to say that if you want to have '... %d{ ...' one need to write it has '.... %d',var,'{ ....', this would permit to have the '..%{var}...' embedding syntax.
> 
> -What to do with non-const char[]?
> They cannot be parsed by the template, so one possibility is to allow only const char[] parameter or to allow non-const char[] and leave them alone (they may contain printf-style format string). This is what the current implementation is doing but I'm not sure if the added flexibility is not confusing: const char[] can contain both printf-like format and 'new embedded format' but non const char[] can only contain printf-like format string.
> 
> - Another possibility would be to use a different character '#' (like in Ruby) for these new format string..
> 
> I'd like some inputs to see if there is a majority in favour of one style or the other..
> 
> renoX

To be honest, I think the type suffix needs to go.  After all, if you
know what the type is at compile-time, why do I need to repeat it?

Of course, doing that leaves you with the problem of how to specify
formatting options... but then in the majority of cases, you probably
don't care; you just want the thing output.

So how about something like this:

Expansion ::= "$" ExpansionSpec

ExpansionSpec ::= FormattingOptions ExpansionExpr
ExpansionSpec ::= ExpansionExpr

FormattingOptions ::= "(" string ")"

ExpansionExpr ::= "{" D_Expression "}"
ExpansionExpr ::= D_Identifier

So the example above becomes "... $(08){var1+var2} ...": one character
longer, but gives you more freedom as to what you can put in the
formatting options.  Plus, if you don't care how it's formatted, you can
use "... ${var1+var2} ...", and if you just want to print a variable
out, you can use "... $somevar ...".

Plus, if you discount the formatting stuff out the front, it's roughly
comparable to how variable expansions are written in bash and the like.
 I also think that Nemerle (which has had this sort of compile-time
printf stuff for ages) does it the same way.

As for the spec itself: it should be const char[] only, and display a
meaningful error if the programmer tries to pass a non-const char[].
That said, I think you should also provide a "run-time" version of the
function that has the exact same parser, formatting, etc., but the user
can pass one or more hash maps to the function.  This would allow people
to use the same format for both compile and runtime, whilst not making
the runtime version a security risk (well, aside from arbitrary
expressions, anyway).  For example:

> auto author = "renoX";
> auto d_bdfl = "Walter Bright";
> auto life = 42;
>
> mixin(swritefln("Author: $author, BDFL: $(q)d_bdfl, "
>     "Meaning of life: $life"));
>
> // Author: renoX, BDFL: "Walter Bright", Meaning of life: 42
>
> char[][char[]] strings;
> int[char[]] ints;
>
> strings["author"] = author;
> strings["d-bdfl"] = d_bdfl;
> ints["life"] = life;
>
> auto formatstr = "Author: $author, BDFL: $(q){d-bdfl}, "
>     "Meaning of life: $life";
>
> writefln(formatstr, strings, ints);
>
> // Prints the same thing as above

	-- Daniel

P.S.  $(q){...} is stolen from Lua's "%q" format specifier: prints a
string out complete with escaping and quotation marks :P

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even
make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/



More information about the Digitalmars-d mailing list