On Sat, Nov 01, 2014 at 06:04:21PM -0700, Walter Bright via Digitalmars-d wrote: > On 11/1/2014 3:26 PM, bearophile wrote: > >But you can run such compile-time tests only on template arguments, > >or on regular arguments of functions/constructors that are forced to > >run at compile-time. But for me this is _not_ enough. You can't > >implement the printf test example he shows (unless you turn the > >formatting string into a template argument of printf, this introduces > >template bloat > > D has writefln which does not have printf's issues. There's no reason > to add a feature for printf. > > When I look at my code, it is very rare that I pass arguments to > functions that would benefit from compile time checking. For those > that might, there's always a rethinking of the feature, such as with > printf/writefln.
I've been thinking about refactoring writefln (well, actually std.format.formattedWrite, which includes that and more) with compile-time validated format strings. I'd say that 90% of code that uses format strings use a static format string, so there's no reason to force everyone to use runtime format strings as is currently done. The advantages of compile-time format strings are: 1) Compile-time verification of format arguments -- passing the wrong number of arguments or arguments of mismatching type will force compilation failure. Currently, it will compile successfully but fail at runtime. 2) Minimize dependencies: the actual formatting routines needed for a particular format string can be determined at compile-time, so that only the code necessary to format that particular format string will be referenced in the generated code. This is particularly important w.r.t. function attributes: currently, you can't use std.string.format from nothrow or @nogc code, because parts of the formatting code may throw or allocate, even if your particular format string never actually reaches those parts. Analysing the format string at compile-time would enable us to decouple the @nogc/nothrow parts of format() from the allocating / throwing parts, and only pull in the latter when the format string requires it, thereby making format() usable from nothrow / @nogc code as long as your format string doesn't require allocation / formatting code that may throw. 3) Compile-time parsing of format string: instead of the runtime code parsing the format string every time, you do it only once at compile-time, and at runtime it's just sequential list of calls to the respective formatting functions without the parsing overhead. This gives a slight performance boost. Granted, this is not that big a deal, but it's a nice side-benefit of having compile-time format strings. The best part about doing this in D is that the same codebase can be used for processing both compile-time format strings and runtime format strings, so we can minimize code duplication; whereas if it were C++, you'd have to implement format() twice, once in readable code, and once as an unreadable tangle of C++ recursive templates. T -- Answer: Because it breaks the logical sequence of discussion. Question: Why is top posting bad?
