October 21, 2023

On Saturday, 21 October 2023 at 03:59:22 UTC, Walter Bright wrote:

>

On 10/20/2023 8:51 PM, Steven Schveighoffer wrote:

>

YAIDIP:

i"axy:  $a{03} $x{e} $y{20.10}"

You and I must be reading a different version of https://github.com/John-Colvin/YAIDIP

May I quote:

That portion is a possible usage. Perhaps the original authors of YAIDIP didn't realize that it's still worth pointing out that it effectively can also be solved with format specifiers. I personally find the C++ style of formatting not as appealing as the writef style. That portion of the DIP lists it as a benefit, but I'm with you on the terseness of format specifications. It really should be more clearly identified as an option, and not an integral part of the proposal.

But that's the whole thing, with a tuple-based solution, you have options in the library. You can use the C++ style or you can use formatting encoded in the string literal. Both are available depending on what you, the library author, would prefer.

And of course, YAIDIP (and 1036) has the benefit that runtime parsing of the string-based format specifiers is not necessary, whereas it is in 1027.

-Steve

October 20, 2023
On 10/20/2023 8:56 PM, Steven Schveighoffer wrote:
> On Saturday, 21 October 2023 at 03:48:49 UTC, Walter Bright wrote:
>> The examples I used are copied verbatim from the YAIDIP. If they're all false, please write a better proposal.
> 
> Your interpretation is false, not the examples.
> 
> They are examples of what's possible, not requirements.

Then, again, a far more thorough proposal is necessary. YAIDIP says nothing at all about `{03}` formats. It gives no examples of them. `{ }` isn't even in the grammar! I'm not making false statements about YAIDIP by saying it doesn't have them, because it doesn't.

How it works needs to be clearly and completely written in the specification.
October 21, 2023

On Saturday, 21 October 2023 at 04:10:35 UTC, Walter Bright wrote:

>

On 10/20/2023 8:51 PM, Steven Schveighoffer wrote:

>

Not even printf works as expected, only writef.

Try doing printf with a string parameter (not a string literal) with DIP1027.

To use printf with i-strings, it's implicitly necessary to use arguments that are compatible with printf. That means const(char)* arguments, not string arguments. This is something that should be obvious once how i-string conversion to tuples works.

DIP1027 has zero knowledge of writef or printf or format.

Yes and no. It's very clearly geared towards writef (or else we would have some other default other than %s), even though it doesn't require hooking with writef. But in effect, writef and format (and other functions like it, such as loggers) are the only functions it works with "out of the box". There are many other functions that use the same style of "blueprint + data" calls which will utterly fail, and can't be made to work with DIP1027.

BTW, I count a failure as having to specify the correct substitution as the user. That is the domain of the function or the type system.

>

--- However ---

Ever since we added printf format checking to the language, I've toyed with the idea of going a step further and adjusting the arguments (and formats) of the calls to printf to make them work.

Nobody, and I really truly mean, NOBODY, is clamoring for better ways to call printf (specifically printf).

And if you are, YAIDIP or DIP1036 is your guy. It can do it, without any specialized compiler help, without allocations, and in betterC mode (as I have demonstrated).

-Steve

October 21, 2023

On Saturday, 21 October 2023 at 04:17:57 UTC, Walter Bright wrote:

>

On 10/20/2023 8:51 PM, Steven Schveighoffer wrote:

>

How can you possibly think that YAIDIP requires allocations?

How else can you make a user-defined dec() work?

I'm not sure I understand this. What is dec()?

> >

The only proposal that requires allocations is DIP1027, since you must rebuild the format string if your function doesn't support printf style format specifiers (i.e. mysql).

The example I gave in the other thread shows how to not need to rewrite the format string.

https://www.digitalmars.com/d/archives/digitalmars/D/Just_another_example_of_missing_string_interpolation_370542.html#N370696

mysql requires a string as the sql for the prepared statement. Basically, you pass a string with a different type of placeholder specifier "?". It does not accept "%s". This is not something I have any control over.

So naturally, since you only get a runtime format string from DIP1027, you need to create an equivalent runtime string to pass to the library. How can you do that without allocations?

>

But even if you did rewrite it, it doesn't escape the template function, and can be RAII'd.

That is not comparable to building the correct string at compile-time. It also requires parsing the format string at runtime.

>

Dealing with a string allocated and returned by dec() is significantly harder.

You will have to expand on what dec() is, I'm unfamiliar with it.

-Steve

October 21, 2023

On Saturday, 21 October 2023 at 04:36:05 UTC, Walter Bright wrote:

>

On 10/20/2023 8:56 PM, Steven Schveighoffer wrote:

>

On Saturday, 21 October 2023 at 03:48:49 UTC, Walter Bright wrote:

>

The examples I used are copied verbatim from the YAIDIP. If they're all false, please write a better proposal.

Your interpretation is false, not the examples.

They are examples of what's possible, not requirements.

Then, again, a far more thorough proposal is necessary. YAIDIP says nothing at all about {03} formats. It gives no examples of them. { } isn't even in the grammar! I'm not making false statements about YAIDIP by saying it doesn't have them, because it doesn't.

That's because it's not part of the proposed feature. It's just an example of how the proposed feature could be used. As is the "scientific" et. al. usage. If you understand the proposal you can understand the possibilities. Hopefully examples help to understand the possibilities without having to enumerate all future infinite possibilities.

That being said, this example in the DIP is poor IMO. It doesn't sell the feature at all, and to me looks like a step down. Technically some people might prefer that style of formatting, but I don't count myself as one of them.

>

How it works needs to be clearly and completely written in the specification.

Agreed. But it is important to note that YAIDIP and 1036 describe a language feature. The section on "Use Cases" is not a set of requirements for the proposal. They are just examples.

I think the DIP could be clearer about what is part of the proposal and what is just an example. It should have a clear statement such as "That concludes the proposal. The following are descriptions of examples that can be realized with the proposed feature, and are in no way requirements of the proposal."

-Steve

October 20, 2023
I expect the grammar would be part of the proposal, not a use case.

In any case, I don't see a point in discussing YAIDIP any further, and will await the real proposal.

October 20, 2023
On 10/20/2023 9:42 PM, Steven Schveighoffer wrote:
> Yes and no. It's very clearly geared towards writef (or else we would have some other default other than %s), even though it doesn't require hooking with writef. But in effect, writef and format (and other functions like it, such as loggers) are the only functions it works with "out of the box".

That's no surprise, since Phobos has adopted that style for more than just writef, such as std.format.format(). There's no reason to invent a different one for loggers.

https://dlang.org/phobos/std_format.html#format

Besides, I had modified DIP1027 to enable any format string between { } specifically to accommodate your database use case.


> There are many other functions that use the same style of "blueprint + data" calls which will utterly fail, and can't be made to work with DIP1027.

Example, please. I already showed how to do Adam's example of things that wouldn't work with DIP1027.


> BTW, I count a failure as having to specify the correct substitution as the user. That is the domain of the function or the type system.

I don't know what that means.

> Nobody, and I really truly mean, NOBODY, is clamoring for better ways to call printf (specifically printf).

Which is too bad. printf has many advantages:

1. small
2. only the call is emitted to the object file
3. several decades spent optimizing it
4. ubiquitous
5. very well documented
6. very battle-tested

(2) is very important when trying to track down a bug, and one needs to examine the object code. D's format checking has eliminated much of the problems using it.

> NOBODY

Nobody wanted ImportC, either. However, several people have told me that they have been seduced into using it and found it delightful and very productive. Heck, in another posting I discovered it could be used to translate C code to D!
October 20, 2023
On 10/20/2023 9:54 PM, Steven Schveighoffer wrote:
> I'm not sure I understand this. What is `dec()`?

From https://github.com/John-Colvin/YAIDIP :

"Consider for example using stream manipulators such as dec and hex for writeln by using an i-string:+"

```
void fun(int x) {
    writeln(i"$dec$x in hexadecimal is 0x$hex$x.");
    // Lowering: --->
    // writeln(.object.imported!"core.interpolation".InterpolationHeader!("", "dec", "", "x", " in hexadecimal is 0x", "hex", "", "x", ".")(),
    //     "", dec, "", x, " in hexadecimal is 0x", hex, "", x, ".");
}
```

And:

"There is no need for defining, implementing, and memorizing a sui generis mini-language of encoded format specifiers"

I wasn't making false statements about that, either.


>> https://www.digitalmars.com/d/archives/digitalmars/D/Just_another_example_of_missing_string_interpolation_370542.html#N370696
> 
> mysql requires a string as the sql for the prepared statement. Basically, you pass a string with a different type of placeholder specifier "?". It does not accept "%s". This is not something I have any control over.

See my example. There's no reason it cannot be extended to replace the %s with whatever is needed. Also, DIP1027 provides the { } syntax enabling insertion of whatever placeholder specifier is needed.


> So naturally, since you only get a runtime format string from DIP1027, you need to create an equivalent runtime string to pass to the library. How can you do that without allocations?

The { } syntax. But even if you needed an allocation, a malloc/free pair will suffice. The problem with dec() is dec() returns an allocated string, so the free gets messy.

>> But even if you did rewrite it, it doesn't escape the template function, and can be RAII'd.
> 
> That is not comparable to building the correct string at compile-time. It also requires *parsing* the format string at runtime.

I'd agree that parsing it is a last resort if the { } also fails. But having implemented formatted writes, I can attest that parsing it is not a big deal. It's scanning till you see the %, then substitute your own version. Of course, using { } means the compiler does it for you at compile time.

October 21, 2023
On 21/10/2023 7:57 PM, Walter Bright wrote:
> I'd agree that parsing it is a last resort if the { } also fails. But having implemented formatted writes, I can attest that parsing it is not a big deal. It's scanning till you see the %, then substitute your own version. Of course, using { } means the compiler does it for you at compile time.

This also means that one formatter doesn't have to know about another formatters format string syntax.

Like how formattedWrite doesn't need to know about GDateTime.

And yes, I have that working today with the ``{:}`` syntax in my codebase. Its great.

This is why I do not agree with Adam about his argument against supporting the format string specifier as part of the language. Having it in the language means it is all nicely unified.
October 21, 2023
On Saturday, 21 October 2023 at 02:22:49 UTC, Adam D Ruppe wrote:
> Note to readers: you don't have to believe second-hand nonsense. There's functional implementations to play with already:
>
> [...]

5. Needs to be fixed with YAIDIP.

Walter, is there currently an implementation of your dip that we could try and experiment with?

I'd like to try. As an end user I o ly care about if it works.

I come back to 3 basic requirements :

1. Don't break existing code
2. Be safe
3. Be reasonably performant

That's about it