Jump to page: 1 2
Thread overview
DIP1027 + Design by Introspection
Feb 02, 2021
Daniel N
Feb 02, 2021
Adam D. Ruppe
Feb 02, 2021
Paul Backus
Feb 02, 2021
Daniel N
Feb 02, 2021
Paul Backus
Feb 02, 2021
Daniel N
Feb 02, 2021
Daniel N
Feb 02, 2021
Adam D. Ruppe
Feb 03, 2021
Daniel N
Feb 02, 2021
12345swordy
Feb 02, 2021
Daniel N
February 02, 2021
DIP1027 + Design by Introspection

Since DIP1027 is simpler than DIP1036 I wanted to take a step back and see what could be done to fix DIP1027 to be even better than DIP1036.

1) q{} is designed for code generation it needs to be supported with Interpolation.
2) DbI

IMHO both DIP1027 and DIP1036 suffers when trying to support custom formatting...
which makes the syntax as hard to read as the original manual writefln format string.

My DIP1027+ proposal is based on UDA and can support any function with trivial syntax.
  printf(i"I ate $apples and $bananas totalling $(apples + bananas) fruit.");
writefln(i"I ate $apples and $bananas totalling $(apples + bananas) fruit.");

Key insight, the function specifies what format it expects.
printf(...)   @formatting!printf_style
writefln(...) @formatting!writefln_style
This way it doesn't have to be repeated in user-facing code over and over.

Basically the compiler will invoke "printf_style!int" and the function will return "%d",
the compiler doesn't know anything about printf, it will just introspect/ask the function.

February 02, 2021
On Tuesday, 2 February 2021 at 15:55:23 UTC, Daniel N wrote:
> Since DIP1027 is simpler than DIP1036

This is a myth, with the exception of the implicit to string conversion.

DIP 1027 had to break up the string and reconstruct a new one while reordering the tuple.

DIP 1036 is a direct syntax rewrite. It just splits the string on the ${ character into a tuple and puts a simple struct wrapper around the string parts so you can identify them. See for yourself how simple the diff is:

https://github.com/dlang/dmd/compare/master...adamdruppe:string_interp

The implicit to string part isn't implemented (gotta figure out how to express `alias toString this;` inside the compiler basically, it might be easy but I don't know how).


> 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.
February 02, 2021
On Tuesday, 2 February 2021 at 16:57:36 UTC, Adam D. Ruppe wrote:
> On Tuesday, 2 February 2021 at 15:55:23 UTC, Daniel N wrote:
>> Since DIP1027 is simpler than DIP1036
>
> This is a myth, with the exception of the implicit to string conversion.
>
> DIP 1027 had to break up the string and reconstruct a new one while reordering the tuple.
>
> DIP 1036 is a direct syntax rewrite. It just splits the string on the ${ character into a tuple and puts a simple struct wrapper around the string parts so you can identify them.

DIP 1027 is a single direct syntax rewrite with no library support required. DIP 1036 is two separate syntax rewrites, plus an algorithm for choosing between them, plus support code for the rewrites in druntime.

DIP 1036 has plenty of advantages compared to DIP 1027, but trying to pretend it is a simpler proposal is just dishonest.
February 02, 2021
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.

February 02, 2021
On Tuesday, 2 February 2021 at 17:04:47 UTC, Paul Backus wrote:
> DIP 1036 has plenty of advantages compared to DIP 1027, but trying to pretend it is a simpler proposal is just dishonest.

I thought the only thing everyone could agree on was that DIP1027 is less complex, at least I could get the gist of it in an instant in contrast to DIP1036.

My mistake, I guess it hasn't been established as a fact, I was not intentionally misleading, for me it was as obvious as "the sky is blue", but people would contest that also since it's not always blue, now is it?

February 02, 2021
On Tuesday, 2 February 2021 at 17:39:06 UTC, Daniel N wrote:
> On Tuesday, 2 February 2021 at 17:04:47 UTC, Paul Backus wrote:
>> DIP 1036 has plenty of advantages compared to DIP 1027, but trying to pretend it is a simpler proposal is just dishonest.
>
> I thought the only thing everyone could agree on was that DIP1027 is less complex, at least I could get the gist of it in an instant in contrast to DIP1036.

Did you mean to reply to Adam instead of me? I agree with you--DIP 1027 is less complex than DIP 1036.
February 02, 2021
On Tuesday, 2 February 2021 at 17:56:32 UTC, Paul Backus wrote:
> On Tuesday, 2 February 2021 at 17:39:06 UTC, Daniel N wrote:
>> On Tuesday, 2 February 2021 at 17:04:47 UTC, Paul Backus wrote:
>>> DIP 1036 has plenty of advantages compared to DIP 1027, but trying to pretend it is a simpler proposal is just dishonest.
>>
>> I thought the only thing everyone could agree on was that DIP1027 is less complex, at least I could get the gist of it in an instant in contrast to DIP1036.
>
> Did you mean to reply to Adam instead of me? I agree with you--DIP 1027 is less complex than DIP 1036.

My bad again ;) Yes!

February 02, 2021
On Tuesday, 2 February 2021 at 17:29:53 UTC, Daniel N wrote:
> 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.

But you have to modify the source code in the library anyway. And then how do you add new styles?

How does @formatting!printf_style actually get applied?
February 02, 2021
On Tuesday, 2 February 2021 at 15:55:23 UTC, Daniel N wrote:
> DIP1027 + Design by Introspection
>
> Since DIP1027 is simpler than DIP1036 I wanted to take a step back and see what could be done to fix DIP1027 to be even better than DIP1036.
>
> 1) q{} is designed for code generation it needs to be supported with Interpolation.
> 2) DbI
>
> IMHO both DIP1027 and DIP1036 suffers when trying to support custom formatting...
> which makes the syntax as hard to read as the original manual writefln format string.
>
> My DIP1027+ proposal is based on UDA and can support any function with trivial syntax.
>   printf(i"I ate $apples and $bananas totalling $(apples + bananas) fruit.");
> writefln(i"I ate $apples and $bananas totalling $(apples + bananas) fruit.");
>
> Key insight, the function specifies what format it expects.
> printf(...)   @formatting!printf_style
> writefln(...) @formatting!writefln_style
> This way it doesn't have to be repeated in user-facing code over and over.
>
> Basically the compiler will invoke "printf_style!int" and the function will return "%d",
> the compiler doesn't know anything about printf, it will just introspect/ask the function.

We don't need more built in attributes to an attribute filled language.

-Alex
February 02, 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
« First   ‹ Prev
1 2