February 04, 2021
On Thursday, 4 February 2021 at 10:38:00 UTC, ddcovery wrote:
> In my opinion,
>
>   `${a} plus ${b} is ${a+b}`
>
> is definitely easier to read than
>
>   "" + a + " plus " + b + " is " + (a+b)

I don't think it is a big difference, of course, JavaScript also converts to string automagically, which makes string interpolation much less useful. Often it is sufficient to just do:

[a, 'plus', b, 'is', a+b].join(' ')


February 04, 2021
On Thursday, 4 February 2021 at 15:39:53 UTC, Ola Fosheim Grøstad wrote:
> of course, JavaScript also converts to string automagically

if and only if you use the default function.

foo`string` in javascript does not necessary convert to string.
February 04, 2021
On Thursday, 28 January 2021 at 06:12:14 UTC, Walter Bright wrote:
> It appears to have abandoned being usable with printf?

After reading through the discussion, would it be more prudent to request that it can be used with printf and @nogc, even if an additional template is required to translate?

D has created a focus on working well without a GC. So it would make sense that new features would be aligned with that concept.

Whereas old language features can both remain using GC and not supporting printf.


```
import std;
import core.stdc.stdio;

@nogc
void main()
{

    auto W = "world" ;
    printf(toStringz("Hello " ~ W ~ " D"));
}
```
February 04, 2021
On Thursday, 4 February 2021 at 15:48:47 UTC, Adam D. Ruppe wrote:
> On Thursday, 4 February 2021 at 15:39:53 UTC, Ola Fosheim Grøstad wrote:
>> of course, JavaScript also converts to string automagically
>
> if and only if you use the default function.
>
> foo`string` in javascript does not necessary convert to string.

Yes, I like the meta-programming aspect, but I think it can be solved by overloading so that foo can be used for other symbols. Does the proposal allow for this?

For instance you could require that templated function

foo__string__interpolation__(…)(…){…}

will only be called if it prefixes foo`string`


Then you could have very short symbols as prefixes without wasting precious symbols.

February 04, 2021
On Wednesday, 3 February 2021 at 16:52:23 UTC, Q. Schroll wrote:
> Getting a string is probably what most users expect most of the time. Handling the secondary type must be explicit. It is almost an implementation detail that shouldn't be exposed to the user too easily.
>
> (I'll post that to the feedback thread as well.)

I 100% agree with this. Reading over the thread, it seems clear that we're trying to pessimize the most common use case to make @system @nogc usage possible... but this is counter to D's design philosophy of doing the correct/convenient thing by default, but also enabling more advanced use cases, potentially with a bit more effort. I think this is the way we should go.

"istrings" (i"", iq{}, i``, etc.) should by default create a GC-managed string literal. This is by far the most intuitive and easy to understand thing to do, and if you're using istrings for code generation, you don't care that it's allocating memory.

However, if you want a tuple sequence as described in the DIP, you can simply call a (probably compiler-supplied) helper method; maybe it doesn't even have to be new: why not .tupleof?

auto apples = 2;
auto bananas = 3;

auto s1 = i"I have ${apples + bananas} fruit";
static assert(is(typeof(s1) == string));

auto s2 = i"I have ${apples + bananas} fruit".tupleof;

Then we can hide all the complexity of interpolated sequences behind the .tupleof (or whatever we decide on) magic property.
February 04, 2021
On Thursday, 4 February 2021 at 16:15:03 UTC, Meta wrote:
> I 100% agree with this. Reading over the thread, it seems clear that we're trying to pessimize the most common use case

How often do you just create a string and not actually do anything with it?

I'm very skeptical most this stuff will actually matter in practice since most cases will be used in function calls.
February 04, 2021
On 4/2/21 17:15, Meta wrote:
> However, if you want a tuple sequence as described in the DIP, you can simply call a (probably compiler-supplied) helper method; maybe it doesn't even have to be new: why not .tupleof?
> 
> auto apples = 2;
> auto bananas = 3;
> 
> auto s1 = i"I have ${apples + bananas} fruit";
> static assert(is(typeof(s1) == string));
> 
> auto s2 = i"I have ${apples + bananas} fruit".tupleof;
> 
> Then we can hide all the complexity of interpolated sequences behind the .tupleof (or whatever we decide on) magic property.

Could this be made so it's transparent to the user of a library?

I.e. in the SQL case, the user of a library just types:

```
auto result = connection.execute(i"SELECT * FROM foo WHERE bar = ${baz}");
```

instead of

```
auto result = connection.execute(i"SELECT * FROM foo WHERE bar = ${baz}".tupleof);
```

If it has to be explicit, how would the signature of Connection.execute(...) look like? How would the user easily know that the function expects an interpolated literal, just by looking at it?
February 04, 2021
On Thursday, 4 February 2021 at 13:44:48 UTC, Adam D. Ruppe wrote:
> On Thursday, 4 February 2021 at 07:09:07 UTC, Daniel N wrote:
>> With a plain tuple it is possible to create a wrapper which generates DIP1036 style lowering (or simply work directly in the template with the value params).
>
> That forces CTFE evaluation of *everything* which is pretty useless.
>
> int bar;
> fun!(i"foo {$bar+5}"); // bar cannot be evaluated at compile time
>

Expressions could simply be lowered to temporaries on demand...

fun!(i"foo ${bar+5}");
======================
(int __expr0) {
  return fun!("foo ", __expr0);
}(bar+5);

Which works perfectly fine, it does archive my goal of reducing the complexity in the *common case*.

Arguably it's even more complex in the case where the lambda is needed, so I can understand if not everyone is happy with my idea... but if it was my proposal I wouldn't even support expressions, plain "$bar" is the sweet spot, no need for ${}, nor temporaries, keep it simple.

Well, maybe you are right about template instance bloat being exaggerated, I didn't benchmark it recently.

/Daniel N

February 04, 2021
On Thursday, 4 February 2021 at 16:27:32 UTC, Adam D. Ruppe wrote:
> I'm very skeptical most this stuff will actually matter in practice since most cases will be used in function calls.

I think it would be better to improve on templates/CTFE so that interpolated strings can be implemented as pure meta programming. Basically some way to say that a prefix for a string matches up with a certain type of template (by name or other means).

Then some way to emit mixins into the calling context, maybe some way to query the calling context.

So if you write:

  writeln(f`Four is {1+3}!`)

The lookup will hit some templated construct f__interpolate__!….

  writeln(f__interpolate__!`Four is {1+3}!`())

Which has special capabilities that allows it to emit:

  writeln(mixin(`tuple("Four is ", (1+3).to!string(), "!").expand`));


D does not need more builtins, improve on pure meta programming instead seems more productive.

February 04, 2021
On Thursday, 4 February 2021 at 15:34:07 UTC, Adam D. Ruppe wrote:
> but you don't know that the opening brace is interpolating.
>
> enum name = "foo";
> mixin(iq{ void {name}() {bar} });
>
>
> Is {bar} interpolation or a function body?

It would be interpolation. If you are in text (string) mode when hitting "{" it would be taken as opening an expression that should be converted to string. So, no ambiguity.