Jump to page: 1 211  
Page
Thread overview
Just another example of missing string interpolation
Oct 12
bachmeier
Oct 12
bachmeier
Oct 12
kdevel
Oct 12
kdevel
Oct 12
bachmeier
Oct 13
kdevel
Oct 13
bachmeier
Oct 13
bachmeier
Oct 13
kdevel
Oct 13
bachmeier
Oct 13
kdevel
Oct 13
kdevel
Oct 13
bachmeier
Oct 13
kdevel
Oct 14
mw
Oct 14
bachmeier
Oct 12
mw
Oct 12
mw
Oct 13
kdevel
Oct 17
jmh530
Oct 20
Daniel N
Oct 19
Daniel N
Oct 19
claptrap
Oct 19
monkyyy
Oct 19
monkyyy
October 12

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

October 12

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

Agreed, as someone who uses C# every day, string interpolation is like the most used feature lol

October 12

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

I agree that string interpolation needs to be added to the language (it's 2023) but for the benefit of an outsider reading your message, there are better options than calling format. I use a generalization of this:

string interp(string s, string[string] subs) {
  foreach(k; subs.keys) {
    s = s.replace("${" ~ k ~ "}", subs[k]);
  }
  return s;
}

For your example, I'd call this

std.file.write("foo.txt",
  interp("${clear}2K\r${white}Progress:${clear}${progress}% \t${white}Speed:${clear} ${curSpeed} ${unit}",
  ["clear": "\x1b[", "white": "\x1b[1m",
   "progress": "0m 50", "curSpeed": "0m 15.5",
   "unit": "KB/s"]));

Would be much better to have this in the language, so I wouldn't have to specify all the substitutions, but a lot better than using format IMO.

October 12

On Thursday, 12 October 2023 at 16:31:39 UTC, bachmeier wrote:

>

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

I agree that string interpolation needs to be added to the language (it's 2023) but for the benefit of an outsider reading your message, there are better options than calling format. I use a generalization of this:

string interp(string s, string[string] subs) {
  foreach(k; subs.keys) {
    s = s.replace("${" ~ k ~ "}", subs[k]);
  }
  return s;
}

For your example, I'd call this

std.file.write("foo.txt",
  interp("${clear}2K\r${white}Progress:${clear}${progress}% \t${white}Speed:${clear} ${curSpeed} ${unit}",
  ["clear": "\x1b[", "white": "\x1b[1m",
   "progress": "0m 50", "curSpeed": "0m 15.5",
   "unit": "KB/s"]));

Would be much better to have this in the language, so I wouldn't have to specify all the substitutions, but a lot better than using format IMO.

or like this:

string enableInterpolation() {
    return q{
        string interp(string s)() {
            import std.algorithm;
            import std.meta;
            import std.array;
            import std.conv;
            import std.functional;
            enum spl = aliasSeqOf!(s.splitter(" ").array) ;

            template P(string e) {
                static if(e.startsWith("$")) {           			
                    mixin("enum P = ()=>"~e[1..$]~".to!string;");
                }
                else {
                    string fn(){ return e;}
                    enum P = &fn;
                }
            }

            return [staticMap!(P, spl)].map!(f=>f()).join(" ");

        }
    };
}

int main() {
    import std.stdio;

    float speed = 42;
    mixin(enableInterpolation());
    writeln(interp!"i has $speed !");

    return 0;
}

October 12

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}");

There are library solutions, e.g shameless self-plug:

https://code.dlang.org/packages/jdiutil

        writeln(mixin(_S!"with    var name: {i; d; thePoint}"));

output:

with    var name: i=100 d=1.23457 thePoint=app.Point(_x=3 _y=0.456 _label=default value _counter=0)
October 12

On Thursday, 12 October 2023 at 17:56:29 UTC, mw wrote:

>

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}");

There are library solutions, e.g shameless self-plug:

https://code.dlang.org/packages/jdiutil

        writeln(mixin(_S!"with    var name: {i; d; thePoint}"));

output:

with    var name: i=100 d=1.23457 thePoint=app.Point(_x=3 _y=0.456 _label=default value _counter=0)

The package is called: Just-Do-It

Because things like this have been talked about so long ,and so many times (and even so many previous DIPs), but nothing materialized.

So, I decided Just-Do-It!

October 12

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

>

or like this:

string enableInterpolation() {
    return q{
        string interp(string s)() {
            import std.algorithm;
            import std.meta;
            import std.array;
            import std.conv;
            import std.functional;
            enum spl = aliasSeqOf!(s.splitter(" ").array) ;

            template P(string e) {
                static if(e.startsWith("$")) {           			
                    mixin("enum P = ()=>"~e[1..$]~".to!string;");
                }
                else {
                    string fn(){ return e;}
                    enum P = &fn;
                }
            }

            return [staticMap!(P, spl)].map!(f=>f()).join(" ");

        }
    };
}

int main() {
    import std.stdio;

    float speed = 42;
    mixin(enableInterpolation());
    writeln(interp!"i has $speed !");

    return 0;
}

I had something like that but moved away from it. The version I posted works better if I want to transform some of the variables. If I do that in a mixin, I have to parse the input. I actually do something like this using a struct:

string s = "String needing interpolation to insert ${y} and ${x}.";
Subs subs;
subs["y"] = str.split("/")[0];
subs["x"] = 2.6*j;
interp(s, subs);

Again, though, this really should be done by the language rather than the user having to mess with it.

October 12

On Thursday, 12 October 2023 at 16:31:39 UTC, bachmeier wrote:

>

[...] I use a generalization of this:

string interp(string s, string[string] subs) {
  foreach(k; subs.keys) {
    s = s.replace("${" ~ k ~ "}", subs[k]);
  }
  return s;
}

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

October 12

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 !");

?

October 12

On Thursday, 12 October 2023 at 19:42:41 UTC, kdevel wrote:

>

On Thursday, 12 October 2023 at 16:31:39 UTC, bachmeier wrote:

>

[...] I use a generalization of this:

string interp(string s, string[string] subs) {
  foreach(k; subs.keys) {
    s = s.replace("${" ~ k ~ "}", subs[k]);
  }
  return s;
}

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

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

What I do in practice is replace ${ in subs[k] with ControlChar.us, then convert ControlChar.us to $ before returning the final result. That's because I would never have ControlChar.us in a string with interpolation, and I don't have to worry about efficiency because it's just not an issue. Your example is something I don't have to worry about very often. This is in no way a solution that would be suitable for the compiler or Phobos. It's a hack that works for me.

« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10 11