The state of string interpolation

Zoadian no at no.no
Fri Dec 7 15:53:03 UTC 2018


Let me clarify my ideas:

The goal is to be able to implement string interpolation _with 
nice syntax_ as library code.
The code we are aiming for is something like this:
```
int a = 5;
int b = 42;
string b = interp!"a is $(a) and b is $(b)";
```

What is possible today?
````
mixin template interp(string S) {
	enum INTERP_RESULT = tuple("a is ", a, " and b is ", b); // 
replace with code that generates tuple at compile time, based on 
S and captured scope variables
}
void main() {
	int a = 5;
	int b = 42;
	mixin interp!"a is $(a) and b is $(b)";
	writeln(INTERP_RESULT);
}
```

So what do we need to support our goal?
a) mixin as expressions
````
mixin template interp(string S) {
	enum INTERP_RESULT = tuple("a is ", a, " and b is ", b); // 
replace with code that generates tuple at compile time, based on 
S and captured scope variables
}
void main() {
	int a = 5;
	int b = 42;
	writeln(mixin interp!"a is $(a) and b is $(b)".INTERP_RESULT);
}
```

b) a way to refer to a symbol inside that mixin automatically 
(Eponymous mixin templates)
    i'm using 'mixin interp =' as a way to say this is an 
Eponymous mixin template. But maybe it is enough to have 'alias 
interp =' or 'enum interp ='.
    like in normal templates: template ASDF(T) { enum ASDF = ...; }
````
mixin template interp(string S) {
	mixin interp = tuple("a is ", a, " and b is ", b); // replace 
with code that generates tuple at compile time, based on S and 
captured scope variables
}
void main() {
	int a = 5;
	int b = 42;
	writeln(mixin interp!"a is $(a) and b is $(b)");
}
```

c) (optional) a way to not require 'mixin' to be repeated at the 
call site.
````
mixin template interp(string S) {
	mixin interp = tuple("a is ", a, " and b is ", b); // replace 
with code that generates tuple at compile time, based on S and 
captured scope variables
}
void main() {
	int a = 5;
	int b = 42;
	writeln(interp!"a is $(a) and b is $(b)");
}
```

A problem that might exist is that you can define multiple things 
inside a mixin template.
but for it to be useable as an mixin expression only one does 
make sense, so my idea was to only allow Eponymous mixin 
templates to be used as mixin expressions.
Also i might be missing something totally obvious and this does 
not work at all. But i think we should try to explore ways to 
make implementation in library code possible _and_ pretty, before 
we implement string interpolation in the compiler.

So looking at this enhancement request 
(https://issues.dlang.org/show_bug.cgi?id=18586), i'd change this 
code:
```
mixin template fun(string body) {
     mixin("auto fun() { "~body~" }");
}
```
to this:
```
mixin template fun(string body) {
     mixin("mixin fun = (){ return "~body~"; }");
//or maybe: mixin("alias fun = (){ return "~body~"; }");
}
```



More information about the Digitalmars-d mailing list