June 26, 2013
On Wednesday, 26 June 2013 at 20:06:43 UTC, H. S. Teoh wrote:
> But if the format string is known at compile-time, and there are
> extraneous arguments, then it should be a warning / error.

We can't do that in D today, unless we do a writefln!"fmt"(args) in addition to writefln(fmt, args...);

tbh I kinda wish we could overload functions on literals though.
June 26, 2013
26-Jun-2013 22:52, H. S. Teoh пишет:
[snip]
> Then throw in the array formatters %(...%), and D format strings will
> totally blow C's stdio out of the water.
>
They are _range_ formatters. Hence infinitely more powerful :)


-- 
Dmitry Olshansky
June 26, 2013
On Thu, Jun 27, 2013 at 12:17:24AM +0400, Dmitry Olshansky wrote:
> 26-Jun-2013 22:52, H. S. Teoh пишет:
> [snip]
> >Then throw in the array formatters %(...%), and D format strings will totally blow C's stdio out of the water.
> >
> They are _range_ formatters. Hence infinitely more powerful :)
[...]

Right.

Although, I don't think they're *infinitely* more powerful... maybe 50 times more, but to be *infinitely* more powerful requires format strings to be Turing-complete. ;-)


T

-- 
If you look at a thing nine hundred and ninety-nine times, you are perfectly safe; if you look at it the thousandth time, you are in frightful danger of seeing it for the first time. -- G. K. Chesterton
June 26, 2013
On 6/26/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Actually this is good because it allows to customize the format string
> to print only a subset of available information (I've actually used this).

Note that this works:

writefln("%d", x, x);

But the following throws since v2.061:

writeln(format("%d", x, x));

std.format.FormatException@C:\dmd-git\dmd2\windows\bin\..\..\src\phobos\std\string.d(2346): Orphan format arguments: args[1..2]

I find the latter to be quite useful for debugging code, and wanted this feature for a long time.
June 26, 2013
27-Jun-2013 00:24, H. S. Teoh пишет:
> On Thu, Jun 27, 2013 at 12:17:24AM +0400, Dmitry Olshansky wrote:
>> 26-Jun-2013 22:52, H. S. Teoh пишет:
>> [snip]
>>> Then throw in the array formatters %(...%), and D format strings will
>>> totally blow C's stdio out of the water.
>>>
>> They are _range_ formatters. Hence infinitely more powerful :)
> [...]
>
> Right.
>
> Although, I don't think they're *infinitely* more powerful... maybe 50
> times more,

What if I just dig up that another 51st range with element type T that works with writefln ? :)

but to be *infinitely* more powerful requires format strings
> to be Turing-complete. ;-)
>
>
> T
>


-- 
Dmitry Olshansky
June 26, 2013
Andrei Alexandrescu:

> Actually this is good because it allows to customize the format string to print only a subset of available information (I've actually used this).

Your use case is a special case that breaks a general rule. That behavour is surprising, and it risks hiding some information silently. I think format() is more correct here. If you want a special behavour you should use a special function as partialWritefln that ignores arguments not present in the format string.

Bye,
bearophile
June 26, 2013
Am Wed, 26 Jun 2013 22:13:29 +0200
schrieb "Adam D. Ruppe" <destructionator@gmail.com>:

> On Wednesday, 26 June 2013 at 20:06:43 UTC, H. S. Teoh wrote:
> > But if the format string is known at compile-time, and there are extraneous arguments, then it should be a warning / error.
> 
> We can't do that in D today, unless we do a writefln!"fmt"(args) in addition to writefln(fmt, args...);
> 
> tbh I kinda wish we could overload functions on literals though.

So the compiler would eagerly turn arguments into compile-time parameters and offer some trait to check if a particular instantiation of writefln made 'fmt' a template argument ?

  static if (__traits(ctKnown, fmt)) {
    // do static analysis of format specifiers
  } else {
    // regular code path
  }

-- 
Marco

June 26, 2013
On Wednesday, 26 June 2013 at 20:51:54 UTC, Marco Leise wrote:
> So the compiler would eagerly turn arguments into compile-time
> parameters and offer some trait to check if a particular
> instantiation of writefln made 'fmt' a template argument ?

Yeah, something like that. Or making literals a different type that we can overload on (which would also be kinda cool for user defined replacements for them).

writefln(T...)(__string_literal fmt, T t)

distinct from string fmt. The literals would always be available at compile time, whether the function is a template or not.
June 26, 2013
Am 26.06.2013 20:52, schrieb H. S. Teoh:
> On Wed, Jun 26, 2013 at 08:08:08PM +0200, bearophile wrote:
>> An interesting blog post found through Reddit:
>>
>> http://randomascii.wordpress.com/2013/06/24/two-years-and-thousands-of-bugs-of-/
> [...]
>> The most common problem they find are errors in the format string of
>> printf-like functions (despite the code is C++):
>
> None of my C++ code uses iostream. I still find stdio.h more comfortable
> to use, in spite of its many problems. One of the most annoying features
> of iostream is the abuse of operator<< and operator>> for I/O. Format
> strings are an ingenious idea sorely lacking in the iostream department
> (though admittedly the way it was implemented in stdio is rather unsafe,
> due to the inability of C to do many compile-time checks).

I have been an adept of iostreams since day one and never understood why people complain so much about them or the operator<< and operator>>
for that matter.

But I try to keep my C++ code clean from C'isms anyway.

--
Paulo



June 26, 2013
On Wed, Jun 26, 2013 at 11:47:32PM +0200, Paulo Pinto wrote:
> Am 26.06.2013 20:52, schrieb H. S. Teoh:
[...]
> >None of my C++ code uses iostream. I still find stdio.h more comfortable to use, in spite of its many problems. One of the most annoying features of iostream is the abuse of operator<< and operator>> for I/O. Format strings are an ingenious idea sorely lacking in the iostream department (though admittedly the way it was implemented in stdio is rather unsafe, due to the inability of C to do many compile-time checks).
> 
> I have been an adept of iostreams since day one and never understood why people complain so much about them or the operator<< and operator>> for that matter.

They're ugly, that's why. :) And misleading to anyone familiar with bit operators.

But that's beside the point. The main problem is that format strings are inadequately replaced by operator<< and its ilk; C++ tried to get around them by introducing the concept of manipulators and whatnot, but that only increased the ugliness of it all. Plus, it made a string of <<'s stateful, (if the previous line sends a manipulator to cout, then subsequent <<'s are subtly modified from their usual behaviour) making it harder to read.

D's writefln is far superior to C's stdio and C++'s iostream, in any case.


> But I try to keep my C++ code clean from C'isms anyway.
[...]

I tried doing that once. It was a rather painful experience. That's the problem with C++: it started out as being C + classes, but then wanted really badly to assume its own identity, so it accumulated a whole bunch of other stuff, but then it never really cut its ties with C, and the old C + classes heritage lives on. As a result, its OO system leaves a lot to be desired when compared with, say, Java, but using it for just C + classes seems underwhelming when there's so much more to the language than just that. So you end up in this limbo where it's more than C + classes, but doesn't quite make it to the level of real OO like Java, and lots of hacks and ugly corner cases creep in to try to hold the tower of cards together. Trying to be free of C'isms only exposed the flaws of C++'s OO system even more. I found that writing C + classes is still the least painful way to use C++.

Fortunately, there's D to turn to. ;-)


T

-- 
Too many people have open minds but closed eyes.