DIP1027 + Design by Introspection

Steven Schveighoffer schveiguy at gmail.com
Tue Feb 2 18:47:48 UTC 2021


On 2/2/21 12:29 PM, Daniel N wrote:
> On Tuesday, 2 February 2021 at 16:57:36 UTC, Adam D. Ruppe wrote:
>>> Key insight, the function specifies what format it expects.
>>> printf(...)   @formatting!printf_style
>>> writefln(...) @formatting!writefln_style
>>
>> DIP 1036 can do this as it is already written! You don't need a magic 
>> UDA, you just overload the function on the interp type as a library 
>> author.
>>
>> Or you can simply call a function inside the interpolation thing if 
>> you want to do custom stuff as a user.
> 
> In my opinion the user-facing interface of my proposal is cleaner as you 
> don't have to introduce an interp template, you won't have to overload 
> anything nor wrap anything.
> 

This is somewhat of a fallacy. You are overloading and wrapping (in a 
severely inflexible way). Just doing it with the compiler instead of an 
actual overload. Knowing how the compiler treats the rewrite is still a 
cognitive load on the user.

And there are several issues:

1. It doesn't help when the function isn't "blueprint then data" style, 
which is costly compared to interleaved data, and only allows one 
interpolation string parameter.
2. It doesn't support "blueprint then data" implementations that require 
positional parameters (for example, Postgresql). And if you wanted 
something to support this, a. you'd have to rename it, as an overload 
would match the existing function, and b. you would still be able to 
call either function with either style (string + args or interpolation 
tuple).
3. It doesn't allow compile-time processing of the format string, nor 
really any useful compile-time introspection that isn't already 
available with the type being passed in the value tuple anyway.
4. There is no mechanism to overload "compiler-provided formats" with 
"user-provided formats". This means the resulting function must still 
guard against invalid input, instead of making it a compiler error 
(except, of course, with the magic help of the compiler specifically for 
printf).

I want to expand a bit on point 1 too. Consider that DIP1036 is a 
straight rewrite of i"a${b}${c}d" as interp!"a", b, c, interp!"d". This 
is straightforward, intuitive, and can be explained easily. DIP1027 is a 
rewrite of i"a${b}${c}d" as "a%s%sd", b, c. This is not intuitive, nor 
cheap. I know it seems intuitive to C programmers, but for sure, 
blueprint+args is NOT intuitive to those not used to printf.

Not only that but guess what functions like printf and writef do. They 
reinterpret the parameters using the blueprint to get them back into 
order. And this means iterating in parallel a PARSED version of the 
blueprint along with the parameters. Why would we want to do something 
that's harder to explain, harder to implement, and ironically round 
tripped from something parsed at compile-time to something that requires 
runtime parsing?

I would note that DIP1027 would be a great CIP. D is not C. We have 
insanely good tools for this. Making it so you can't use introspection 
tools is not my idea of "better".

-Steve


More information about the Digitalmars-d mailing list