Print formatting goes a long way back. The problem to be solved is to format and print values of various types, in a way appropriate to the type.
C printf does this with a format string, with embedded format specifiers that specify the type of the corresponding argument. The flaw in this, of course, is it's up to the user to get the types right. It is not inherently typesafe.
D1's writefln did it by adding a hidden additional hidden argument that identified the types of each of the arguments. The flaw here is the cost of the TypeInfo which has to be created for each type.
D2's writefln did it by making writefln a variadic template. Then, with compile time introspection, the template generates a custom writefln for each instance. The flaw here is the instantiation of a large number of templates, consuming a lot of space in the executable, and slowing down builds. If it's possible to say, it's been *too* successful!
I'd like to find a way to make a writefln that is typesafe, efficient, and needs only one instance.
I realized that the answer is the printf format string. (printf is small, fast, and compact.) It has, embedded in it, the types of each argument. We just have to eliminate the type unsafe aspect of this.
The way to do it is to mark the first parameter of writefln as a format string. Use %s as formats. Have the compiler then patch the %s to %d, %g, etc., as necessary. Formats like %02x will remain untouched, but the corresponding argument's type will be compiler checked to be a suitable match for it.
We're already nearly there with the pragma(printf) directive to check printf arguments against the format string. Fixing the format string is the next logical step.
Comment #1 by bugzilla — 2024-01-05T21:40:05Z
Arguments like `struct S { int x; int y; }` that have no corresponding format specifier could use `%s` as the format specifier, and then the argument can be wrapped in a template that provides a default toString() method.
Comment #2 by elpenguino+D — 2024-01-05T21:59:43Z
Please fix templates instead of implementing awkward workarounds at every opportunity...
Comment #3 by bugzilla — 2024-01-06T01:52:06Z
The build system, of course, will merge identical template instantiations. But the purpose of templates is to provide specializations for their specific arguments, and so they are different and cannot be merged. writefln() can easily create hundreds of slightly different template instantiations, none of which can be merged.
Comment #4 by maxhaton — 2024-01-07T18:50:20Z
Have you tried fixing writefln first? If you write a good template it will mostly be reused other the parent instantiation.
Comment #5 by robert.schadek — 2024-12-13T19:32:24Z