Thread overview
[phobos] Changing the semantics of std.string.format
Mar 03, 2011
kenji hara
Mar 03, 2011
Don Clugston
March 03, 2011
I've looked into issue 5687, 'std.string.format() error with "%a"'.

    http://d.puremagic.com/issues/show_bug.cgi?id=5687

In short, the problem is that format() calls std.format.doFormat(),
which converts all floating-point numbers internally to 80-bit reals.
For "%a", this is most definitely *not* what you want.

I think it will be a hassle to fix doFormat(), and it looks to me as
though it's headed for deprecation anyway, being replaced by
formattedWrite().

I say the way to go is to rewrite format() in terms of formattedWrite(),
like this:

    string format(String, Args...)(String fmt, Args args)
        if (isSomeString!String)
    {
        auto app = appender!string();
        formattedWrite(app, fmt, args);
        return app.data;
    }

This is nice and simple, and it will make format() consistent with
writefln().  The problem is that it is a breaking change.

The biggest problem is the following, because it won't be caught at compile time and produces subtly different results at run time.

    // before
    assert (format("%s", 123, 456) == "123456");

    // after
    assert (format("%s", 123, 456) == "123");

The following currently works, but won't compile after the change:

    assert (format(123, " %a", 1.0) == "123 0x8p-3");
    assert (format(123, 456) == "123456");

I don't really think these two are a problem, though, because the first one is rather obscure, while the second case is now taken care of by std.conv.text().

Does anyone object to me making this change to format()?

-Lars




March 03, 2011
Perfectly indeed.

We cannot also use "%( ... %)" with std.string.format.

Kenji

2011/3/3 Lars Tandle Kyllingstad <lars at kyllingen.net>:
> I've looked into issue 5687, 'std.string.format() error with "%a"'.
>
> ? ?http://d.puremagic.com/issues/show_bug.cgi?id=5687
>
> In short, the problem is that format() calls std.format.doFormat(),
> which converts all floating-point numbers internally to 80-bit reals.
> For "%a", this is most definitely *not* what you want.
>
> I think it will be a hassle to fix doFormat(), and it looks to me as
> though it's headed for deprecation anyway, being replaced by
> formattedWrite().
>
> I say the way to go is to rewrite format() in terms of formattedWrite(),
> like this:
>
> ? ?string format(String, Args...)(String fmt, Args args)
> ? ? ? ?if (isSomeString!String)
> ? ?{
> ? ? ? ?auto app = appender!string();
> ? ? ? ?formattedWrite(app, fmt, args);
> ? ? ? ?return app.data;
> ? ?}
>
> This is nice and simple, and it will make format() consistent with
> writefln(). ?The problem is that it is a breaking change.
>
> The biggest problem is the following, because it won't be caught at compile time and produces subtly different results at run time.
>
> ? ?// before
> ? ?assert (format("%s", 123, 456) == "123456");
>
> ? ?// after
> ? ?assert (format("%s", 123, 456) == "123");
>
> The following currently works, but won't compile after the change:
>
> ? ?assert (format(123, " %a", 1.0) == "123 0x8p-3");
> ? ?assert (format(123, 456) == "123456");
>
> I don't really think these two are a problem, though, because the first one is rather obscure, while the second case is now taken care of by std.conv.text().
>
> Does anyone object to me making this change to format()?
>
> -Lars
>
>
>
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
March 03, 2011
On 3 March 2011 09:53, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
> I've looked into issue 5687, 'std.string.format() error with "%a"'.
>
> ? ?http://d.puremagic.com/issues/show_bug.cgi?id=5687
>
> In short, the problem is that format() calls std.format.doFormat(),
> which converts all floating-point numbers internally to 80-bit reals.
> For "%a", this is most definitely *not* what you want.

No, that's perfectly fine. Actually, it's a Linux-specific %a bug.

OTOH what you're proposing may be a good idea; it just has NOTHING to do with that bug!
March 03, 2011
On Thu, 2011-03-03 at 10:22 +0100, Don Clugston wrote:
> On 3 March 2011 09:53, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
> > I've looked into issue 5687, 'std.string.format() error with "%a"'.
> >
> >    http://d.puremagic.com/issues/show_bug.cgi?id=5687
> >
> > In short, the problem is that format() calls std.format.doFormat(),
> > which converts all floating-point numbers internally to 80-bit reals.
> > For "%a", this is most definitely *not* what you want.
> 
> No, that's perfectly fine. Actually, it's a Linux-specific %a bug.
> 
> OTOH what you're proposing may be a good idea; it just has NOTHING to do with that bug!

I stand corrected.

I'd still like to rewrite format(), though. :)

-Lars