October 12, 2023

On Thursday, 12 October 2023 at 13:39:46 UTC, Andrea Fontana wrote:

>

Real life example. Render a string like this:

\x1b[2K\r\x1b[1mProgress:\x1b[0m 50% \x1b[1m\tSpeed:\x1b[0m 15.5 KB/s

now (error prone and difficult to debug, try to code it!):

stderr.write(format("%s\r%sProgress:%s %5.1f%% %s\tSpeed:%s %6.1f %s%s", clear, white, clear, progress, white, clear, curSpeed, unit));

(or with string concat, good luck!)

vs:

stderr.write("${clear}\r{$white}Progress:${clear}${progress}% \t${white}Speed:${clear} ${curSpeed} ${unit}");

Andrea

If you are using write* then you can simply do this:

stderr.write(clear,"\r",white,"Progress:",clear," ",progress,"% ",white,"\tSpeed:",clear," ",curSpeed," ",unit);

If you want just to get a string - use text:

stderr.write(text(clear,"\r",white,"Progress:",clear," ",progress,"% ",white,"\tSpeed:",clear," ",curSpeed," ",unit));

The result is the same so IMHO text is good alternative to string interpolation.

You can also wrap styling into functions to make code more readable:

string white(A...)(A args)
{
    return text("\x1b[1m", args, "\x1b[0m");
}

stderr.write(clear,"\r",white("Progress: "),progress,"% \t",white("Speed: "),curSpeed," ",unit);
October 13, 2023

On Thursday, 12 October 2023 at 13:39:46 UTC, Andrea Fontana wrote:

>

Real life example. Render a string like this:

\x1b[2K\r\x1b[1mProgress:\x1b[0m 50% \x1b[1m\tSpeed:\x1b[0m 15.5 KB/s

now (error prone and difficult to debug, try to code it!):

Where is the specific problem?

import std.stdio;
int main (string [] args)
{
   enum fmt = "\x1b[2K\r\x1b[1mProgress:\x1b[0m %s%% \x1b[1m\tSpeed:\x1b[0m > %s KB/s";
   writeln (fmt);
   writefln!fmt (75, 11.11);
   return 0;
}

$ ./prgs
Progress: %s%%  Speed: > %s KB/s
Progress: 75%   Speed: > 11.11 KB/s

The words Progress and Speed appear highlighted in my console.

October 13, 2023

On Thursday, 12 October 2023 at 21:45:55 UTC, bachmeier wrote:

> >

[...]
What if s is "${a}" and subs is ["a": "${b}", "b": "x"]?

That's the reason it needs to be supported by the language.

The problem with your code is that it loops over the wrong list.
It should iterate over the variable occurrences in the string s.

Granted that the language does support interpolation (DIP 1027):
How would you implement your function

string interp(string s, string[string] subs)

in terms of that built-in interpolation?

October 13, 2023

On Thursday, 12 October 2023 at 19:56:48 UTC, kdevel wrote:

>

On Thursday, 12 October 2023 at 17:25:09 UTC, Commander Zot wrote:

>

[...]
writeln(interp!"i has $speed !");

What about

writeln(interp!"i has $speed,$speed !");

?

my code was just an example, you'd have to properly do the parsing of the string. but there are already packages on dub for that

October 13, 2023

On Friday, 13 October 2023 at 12:04:18 UTC, kdevel wrote:

>

On Thursday, 12 October 2023 at 21:45:55 UTC, bachmeier wrote:

> >

[...]
What if s is "${a}" and subs is ["a": "${b}", "b": "x"]?

That's the reason it needs to be supported by the language.

The problem with your code is that it loops over the wrong list.
It should iterate over the variable occurrences in the string s.

That depends. If you don't want to do all of the substitutions, either because you potentially have ${something} as part of the final string, or because you don't want to do all substitutions at once, those cases are trivially handled by my function. It works for what I do.

October 13, 2023

On Friday, 13 October 2023 at 14:25:34 UTC, bachmeier wrote:

>

On Friday, 13 October 2023 at 12:04:18 UTC, kdevel wrote:

>

On Thursday, 12 October 2023 at 21:45:55 UTC, bachmeier wrote:

> >

[...]
What if s is "${a}" and subs is ["a": "${b}", "b": "x"]?

That's the reason it needs to be supported by the language.

The problem with your code is that it loops over the wrong list.
It should iterate over the variable occurrences in the string s.

That depends. If you don't want to do all of the substitutions, either because you potentially have ${something} as part of the final string, or because you don't want to do all substitutions at once, those cases are trivially handled by my function. It works for what I do.

An example of a pattern I sometimes use:

string foo(string s) {
// Do a computation and substitute the result into s
// return the new s
}

string bar(string s) {
// Do a computation and substitute the result into s
// return the new s
}

string s = "String needing interpolation to insert ${y} and ${x}.";
string s2 = foo(s);
string s3 = bar(s2);
October 13, 2023

On Friday, 13 October 2023 at 14:25:34 UTC, bachmeier wrote:

>

On Friday, 13 October 2023 at 12:04:18 UTC, kdevel wrote:

>

On Thursday, 12 October 2023 at 21:45:55 UTC, bachmeier wrote:

> >

[...]
What if s is "${a}" and subs is ["a": "${b}", "b": "x"]?

That's the reason it needs to be supported by the language.

The problem with your code is that it loops over the wrong list.
It should iterate over the variable occurrences in the string s.

That depends. If you don't want to do all of the substitutions,

You don't have to do all substitutions in one go. If a key is missing
in subs one alternative to throwing MissingKey could be to silently
skip that variable occurrence.

>

either because you potentially have ${something} as part of the final string,

How do you convey that intent inside the string? format does it by
estabilishing a special syntax for % (%% -> %).

How do you handle that case with DIP 1027?

And reminder: How do you implement your interp function in terms of
DIP 1027's string interpolation?

October 13, 2023

On Friday, 13 October 2023 at 14:31:01 UTC, bachmeier wrote:

>

[...]
An example of a pattern I sometimes use:

string foo(string s) {
// Do a computation and substitute the result into s
// return the new s

At which position? Which pseudo-variable is substituted in s?

Your functions foo and bar both not only make calls to interp but they
also necessarily contain, in order to succeed, the name of the variable.

>
}

string bar(string s) {
// Do a computation and substitute the result into s
// return the new s
}

string s = "String needing interpolation to insert ${y} and ${x}.";
string s2 = foo(s);
string s3 = bar(s2);

Your approach creates more dependencies between unrelated components than necessary.

How do you unittest foo and bar?

The dependencies can easily be avoided if foo and bar only returned the value of the computation, the results are stored in the AA given as subs in the call to interp.

October 13, 2023

On Friday, 13 October 2023 at 15:16:27 UTC, kdevel wrote:

> >

either because you potentially have ${something} as part of the final string,

How do you convey that intent inside the string? format does it by
estabilishing a special syntax for % (%% -> %).

I don't need to.

>

How do you handle that case with DIP 1027?

And reminder: How do you implement your interp function in terms of
DIP 1027's string interpolation?

I don't know, but I also don't know why I would want to, because DIP 1027 was not accepted.

October 13, 2023

On Friday, 13 October 2023 at 15:34:59 UTC, kdevel wrote:

>

Your functions foo and bar both not only make calls to interp but they
also necessarily contain, in order to succeed, the name of the variable.

Yes

>

Your approach creates more dependencies between unrelated components than necessary.

Then don't use it? The goal of programming is to get the right output.

>

How do you unittest foo and bar?

The same as any other function.

>

The dependencies can easily be avoided if foo and bar only returned the value of the computation, the results are stored in the AA given as subs in the call to interp.

I prefer less complicated code to code that imposes arbitrary restrictions.