Just another example of missing string interpolation

Commander Zot no at no.no
Thu Oct 12 17:25:09 UTC 2023


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

```


More information about the Digitalmars-d mailing list