String Interpolation

Arafel er.krali at gmail.com
Thu Oct 26 16:42:23 UTC 2023


On 26/10/23 18:14, bachmeier wrote:
> I'd agree if the only thing I cared about is good language design and 
> didn't care at all about usability. Why not this?
> 
> |import std.format; string s = $"Hello, ${world}"; |
> 
> Anyone that wants what's currently on offer could still do this if they 
> want:
> 
> |string s = i"Hello, ${world}".format; |
Also, not allowing this would result confusing to new users for no good 
reason: you'll have to explain to them why `write(i"....");` works, but 
`string s = i"....";` doesn't, and how `i"..." isn't like `r"..." or 
`q"[...]"`.

And then, if I have to do `i"Hello, ${world}".format`, I can already 
just as well do `mixin(i!"Hello, ${world}")`. This doesn't require any 
change to the language and has the advantage (as a user) that it's a 
library solution and I can pick the one that best suits my needs.

But back to usability: that is the basic objective of the feature. 
Usability for the end user, not for the library writer.

String interpolation is meant to be high level syntax sugar to make 
things easy and straightforward, not some advanced topic where you need 
to understand how internal compiler tuples work to be able to know when 
you can use it.

So what will 90% of the users want and expect?

Just something that can act as a drop-in replacement for strings for 
basic usage, nothing fancy, don't care about performance. I use this all 
the time for scripting (bash, perl) and it's really convenient.

In D I'd like to do:

```d
// Read config
string basePath = readConfig("basePath");
string inputFolder = readConfig("inputFolder");
string outputFoler = readConfig("outputFolder");
Item[] items = readConfig("itemList");

// Process items
foreach(item; items) {
	string inputFile = i"${basePath}/${inputFolder}/${item.name}.in";
	string outputFile = i"${basePath}/${outputFolder}/${item.name}.out";
	log(i"Going to process input file ${inputFile}. Output will be written 
to ${outputFile}").
	processItem(item, inputFile, outputFile);
}
```

I write this kind of code all the time... in languages that support it. 
I would in D as well, if I had the feature. And yes, adding `.text` or 
`.format` would kill it just as adding `mixin(...)` does already.

Before somebody says I should just adapt `processItem`: in most cases I 
don't have control over it, and the creator of that library isn't likely 
in the mood to deal with templates and tuples, especially with two 
arguments. Why should he? He just wants two file names... and it could 
even be a C library.


More information about the Digitalmars-d mailing list