Thread overview
overcomming inconsistent behaviour of format for array
Dec 26, 2019
berni44
Dec 26, 2019
rikki cattermole
Dec 26, 2019
berni44
Dec 26, 2019
rikki cattermole
Dec 26, 2019
berni44
Dec 26, 2019
user1234
December 26, 2019
You're probably pretty well aware, that format prints quotes arround strings, when the strings are inside of an array, while not doing so, when not. To avoid this, a dash-flag can be used. This causes problems, when width is also specified, because the dash has now two different meanings: Left-justification and quote-removal. Adding to this, the current implementation is inconsistent with justification/width. See also [1], where I ran into problems, while fixing this. Here a few examples:

---
import std.stdio;

void main()
{
    writefln(">%s<", [1, 2]);
    writefln(">%-s<", [1, 2]);
    writefln(">%s<", ["one", "two"]);
    writefln(">%-s<", ["one", "two"]);
    writeln("==================================================");
    writefln(">%20s<", [1, 2]);
    writefln(">%-20s<", [1, 2]);
    writefln(">%20s<", ["one", "two"]);
    writefln(">%-20s<", ["one", "two"]);
    writeln("==================================================");
    writefln(">%(%s, %)<", [1, 2]);
    writefln(">%-(%s, %)<", [1, 2]);
    writefln(">%(%s, %)<", ["one", "two"]);
    writefln(">%-(%s, %)<", ["one", "two"]);
    writeln("==================================================");
    writefln(">%20(%s, %)<", [1, 2]);
    writefln(">%-20(%s, %)<", [1, 2]);
    writefln(">%20(%s, %)<", ["one", "two"]);
    writefln(">%-20(%s, %)<", ["one", "two"]);
    writeln("==================================================");
    writefln(">%(%20s, %)<", [1, 2]);
    writefln(">%-(%20s, %)<", [1, 2]);
    writefln(">%(%20s, %)<", ["one", "two"]);
    writefln(">%-(%20s, %)<", ["one", "two"]);
    writeln("==================================================");
    writefln(">%50(%20s, %)<", [1, 2]);
    writefln(">%-50(%20s, %)<", [1, 2]);
    writefln(">%50(%20s, %)<", ["one", "two"]);
    writefln(">%-50(%20s, %)<", ["one", "two"]);
}
---

produces:

---
>[1, 2]<
>[1, 2]<
>["one", "two"]<
>["one", "two"]<
==================================================
>[                   1,                    2]<
>[1                   , 2                   ]<
>["one", "two"]<
>["one", "two"]<
==================================================
>1, 2<
>1, 2<
>"one", "two"<
>one, two<
==================================================
>1, 2<
>1, 2<
>"one", "two"<
>one, two<
==================================================
>                   1,                    2<
>                   1,                    2<
>"one", "two"<
>                 one,                  two<
==================================================
>                   1,                    2<
>                   1,                    2<
>"one", "two"<
>                 one,                  two<
---

While thinking how to overcome this, I came up with the idea of adding a %S specifier with the meaning "Sourcecode literal", i.e. whenever you use %S, the result can be put into D source code, reproducing the original item. With this it seems to me much easier to get format right, although it's of course still a breaking change.

A rough outline would be:

a) Implement %S for all types but classes, structs, unions and interfaces
   (they are more difficult and IMHO they should be left to the toString
    implementation of those items)
b) Add a transition switch
c) Depending on the switch make %s do, what it should do (i.E. no quotes)
   or what it does now
d) When the deprecation phase is over, remove the current behaviour of %s
   (and the transition switch)

IMHO this has several additional benefits:

* Issue 16190 [2] could be solved without any bracking change
  (fully qualified enums)
* A fast algorithm like grisu or ryu could be used for %S and floats
  (which several people wished to have in phobos)
* %S can be consistently used in mixins etc., while %s always addresses
  human readable output

I think, this will end up, being a DIP, but before writing the DIP in all details, I'd like to get some feedback. :-) What do you think about it?

[1] https://issues.dlang.org/show_bug.cgi?id=9592
[2] https://issues.dlang.org/show_bug.cgi?id=16190
December 27, 2019
On 27/12/2019 1:19 AM, berni44 wrote:
> I think, this will end up, being a DIP, but before writing the DIP in all details, I'd like to get some feedback. :-) What do you think about it?

Why would this need a DIP?
There are no language changes described in your post.
December 26, 2019
On Thursday, 26 December 2019 at 12:31:25 UTC, rikki cattermole wrote:
> Why would this need a DIP?
> There are no language changes described in your post.

OK. I just thought, because it will be breaking code and should be supported by the community? Also deprecating the current behaviour seems not so easy and I think it would be best to have some transition switch for the compilers (like with complex). But if that's not enought, to have a DIP, it's fine for me too. :-)

December 26, 2019
On Thursday, 26 December 2019 at 12:19:56 UTC, berni44 wrote:
> You're probably pretty well aware, that format prints quotes arround strings, when the strings are inside of an array, while not doing so, when not. To avoid this, a dash-flag can be used. This causes problems, when width is also specified, because the dash has now two different meanings: Left-justification and quote-removal. Adding to this, the current implementation is inconsistent with justification/width. See also [1], where I ran into problems, while fixing this. Here a few examples:
>
> [...]
>
> I think, this will end up, being a DIP, but before writing the DIP in all details, I'd like to get some feedback. :-) What do you think about it?

Some languages have an option struct for their format. In D and if not existing yet this would be like adding a new global `__gshared FormatOption formatOption`. controlling the deprecation period from there would be possible.
December 27, 2019
On 27/12/2019 2:03 AM, berni44 wrote:
> On Thursday, 26 December 2019 at 12:31:25 UTC, rikki cattermole wrote:
>> Why would this need a DIP?
>> There are no language changes described in your post.
> 
> OK. I just thought, because it will be breaking code and should be supported by the community? Also deprecating the current behaviour seems not so easy and I think it would be best to have some transition switch for the compilers (like with complex). But if that's not enought, to have a DIP, it's fine for me too. :-)

With changing formattedWrite, we have to consider printf for what we support. This isn't about D, its about historical (and current) C code unfortunately.
December 26, 2019
On Thursday, 26 December 2019 at 13:15:15 UTC, rikki cattermole wrote:
> With changing formattedWrite, we have to consider printf for what we support. This isn't about D, its about historical (and current) C code unfortunately.

Why? Are there any reasons, why we need to stick with what printf does? Can't we do it better than printf? As far as I know, we allready do some stuff that printf can't, while we forego other things that printf does...