October 27, 2023
On Friday, October 27, 2023 7:20:33 AM MDT IGotD- via Digitalmars-d wrote:
> On Friday, 27 October 2023 at 12:55:35 UTC, Arafel wrote:
> > Not possible. A string in D is just another name (literally, just an alias) for an array of immutable chars. So there is no string class, and no constructor to speak of, other than the generic array constructor.
> >
> > Technically, the best solution would probably be to return a (templated) struct with an "alias this" to the already interpolated string, and all other interpolation information also included, so functions would be able to choose what to accept.
> >
> > But "alias this" is just a way to have implicit casting, and that's something (probably rightly) opposed here on principle, so I don't think we'll be having it anytime soon.
>
> Why does this work?
>
> void func(string a)
> {
> ...
> }
>
> func("string literal");

Because the type of "string literal" is string  - which as Arafel correctly points out is immutable(char)[]. No conversion is taking place here whatsoever.

Now, the compiler does have some extra logic where it will potentially
treat a literal as other types for you. E.G. if func took wstring,
it would just treat the literal as a wstring instead of explicitly requiring
that you use "string literal"w. Similarly, you can do

ubyte i = 1; // 1 is an int
ushort[] arr = [1, 2, 42, 22]; // the array literal is int[]

Literals have a default type which you can see if you use typeof on them, but they can be treated as a variety of types by the compiler (null and [] are really good examples of that). And that's different from implicit conversions, because the kind of conversions that are allowed are sometimes completly different from what you can do with actual variables (e.g. you can't convert int[] to ubyte[] like the compiler will do with literals without allocating an entirely different array).

Once a literal is assigned to a variable (or even simply cast to
a specific type), then you're converting a value with a fixed type, not a
literal, and the normal rules for conversion are followed.

And the compiler couldn't do the kind of stuff that it does with literals with interpolated strings, because those aren't values that are known at compile time. The compiler is then dealing with actual objects with a specific type rather than a literal that can be interpreted as a variety of types based on how it's used.

Of course, we could have implicit conversions to string from whatever the string inteperolation generates (e.g. by having alias this on that type), but then that opens up all of the doors that implicit conversions do, which is particularly problematic with generic code. It also requires that the type know how to convert itself to a string as opposed to providing a building block for library code to generate a string from it, which would mean putting the formatting logic in the compiler, which arguably isn't a great idea.

- Jonathan M Davis



October 27, 2023
On 27/10/23 14:49, jmh530 wrote:
> I tried to think of when I just want a string after doing interpolation (as opposed to writing immediately somehow) and struggled a bit.

I, on the other hand, do it constantly, especially when dealing with external libraries / systems.

Here is the first short and almost self-contained real-world example that I found having a quick look at my code. Just see how I construct and use `mailOrder` and `input`:

```d

/* This is another function in my small utility library.
 * Spawns a process, eventually remotely, with the given command line and standard input, returning a tuple with the status code, the captured stdout and the captured stderr.
 */
auto pipeProcess(string command, string stdin, string host = null, string remoteLauncher = "ssh");

bool sendEmail(string toAddr, string fromAddr, string fromName, string subject, string body, bool dryRun = false) {
    string mailOrder = "sendmail -f" ~ fromAddr ~ " -F\"" ~ fromName ~ "\" " ~ toAddr;
    string input = "To: " ~ toAddr ~ "\nSubject: " ~ subject ~ "\n" ~ body;

    try {
        if (!dryRun) {
            auto mailExec = pipeProcess(mailOrder, input);
            if (mailExec.status != 0) {
                error("Error sending mail order: ", mailOrder,"\nstdin\n-----\n", input,
                        "stdout\n------\n", mailExec.output,
                        "\nstderr\n------\n", mailExec.error);
                return false;
            }
        } else {
            warning("DRY RUN: not sending message:", mailOrder,"\n", input);
        }
    } catch (Exception e) {
        error(e);
        return false;
    }
    return true;
}
```

It would be fun, because `error` and `warning` would take interpolated strings directly, but I would need to add `.text` to construct `mailOrder` and `input`. Not confusing at all.

And please let's not start into why I call sendmail, why I don't use an existing mail library, or why I don't implement a SMTP client myself. Any of these solutions could probably be made to work, but would take longer and wouldn't be as simple, flexible, and adapted to **my** needs as this. Also, this already exists and works.

I also don't care about the glaring command injection possibility here, because this code has no user interaction whatsoever with all the inputs controlled by me. Also, how exactly would making me add `.text` prevent the injection?

Now you will tell me, I could rewrite pipeProcess to accept interpolated strings **as well**. But even if I only consider the first two parameters that I'm using in this example, I'd need four overloads: one taking both strings, one taking both interpolated strings, and one for each of the parameters as interpolated string. Less than optimal.

Well, or do some template parameter wizardry which I'm not exactly keen on. How would that work with default parameters, by the way?

Heck, anyway, what about the last two parameters? Who knows if I will ever want to do:

```d
remoteLauncher = "ssh -l " ~ userName ~ " -i " ~ identityFile;
```

Should my `pipeProcess` also accept interpolated strings there? How many overloads do I need now?
October 27, 2023

On Saturday, 21 October 2023 at 12:43:15 UTC, Adam D Ruppe wrote:

>

On Saturday, 21 October 2023 at 12:38:52 UTC, Commander Zot wrote:

>

can we please just have i"whatever ${var}" to return a fully interpolated string

No. Please discontinue this thread, we've been over this a million times, no point doing it again.

It's funny to see people defending interpolated strings shouldn't be string

October 27, 2023
On Friday, 27 October 2023 at 12:55:35 UTC, Arafel wrote:
> On 27/10/23 13:59, Imperatorn wrote:
>> [...]
>
> Not possible. A string in D is just another name (literally, just an alias) for an array of immutable chars. So there is no string class, and no constructor to speak of, other than the generic array constructor.
>
> Technically, the best solution would probably be to return a (templated) struct with an "alias this" to the already interpolated string, and all other interpolation information also included, so functions would be able to choose what to accept.
>
> But "alias this" is just a way to have implicit casting, and that's something (probably rightly) opposed here on principle, so I don't think we'll be having it anytime soon.

I don't mean any of those solutions. I mean that it would do what C# does for example.
October 27, 2023
On Friday, 27 October 2023 at 13:00:37 UTC, Timon Gehr wrote:
> On 10/26/23 19:38, Imperatorn wrote:
>>>
>>> I'm sympathetic to not putting that functionality in the compiler.
>> 
>> And the users are not. That's all I'm saying.
>
> I think it's a bit offensive to say people who do not agree with you are not users of the language.

What has agreeing to do with any of this? It's just facts. Usage = you use it. If you don't use it, then you won't have a problem with it.

You just want to use the breaks in your car, you don't want to be unable to break just because some engineer thought it would be a good idea to add a captcha or solve a little puzzle before you can break.

That basically what the current implementation does. It forces the user to do something they are not used to having to do in any of the other 25+ languages they used before.

As I wrote before, it breaks the interface that is already established. Of course you can break it, but then you can't also be surprised if users complain.
October 27, 2023

On Friday, 27 October 2023 at 14:19:01 UTC, Hors wrote:

>

On Saturday, 21 October 2023 at 12:43:15 UTC, Adam D Ruppe wrote:

>

On Saturday, 21 October 2023 at 12:38:52 UTC, Commander Zot wrote:

>

can we please just have i"whatever ${var}" to return a fully interpolated string

No. Please discontinue this thread, we've been over this a million times, no point doing it again.

It's funny to see people defending interpolated strings shouldn't be string

I didn't think this level of comedy existed, but it seems we have reached a new level of existence.

I tried giving this conversation to GPT but it said "I'm sorry, the content you provided is to surreal, it cannot be captured in this plane of reality"

That's cool!

October 27, 2023
On 10/27/23 16:35, Imperatorn wrote:
> On Friday, 27 October 2023 at 13:00:37 UTC, Timon Gehr wrote:
>> On 10/26/23 19:38, Imperatorn wrote:
>>>>
>>>> I'm sympathetic to not putting that functionality in the compiler.
>>>
>>> And the users are not. That's all I'm saying.
>>
>> I think it's a bit offensive to say people who do not agree with you are not users of the language.
> 
> What has agreeing to do with any of this? It's just facts. Usage = you use it. If you don't use it, then you won't have a problem with it.
> ...

You conduct yourself as if there was some group of powerful stakeholders called "users" with a uniform and informed opinion on this matter that elected you as a representative.

I am a user of D. You don't speak for me.

> You just want to use the breaks in your car, you don't want to be unable to break just because some engineer thought it would be a good idea to add a captcha or solve a little puzzle before you can break.
> 
> That basically what the current implementation does.

No, that's not true.

> It forces the user to do something they are not used to having to do in any of the other 25+ languages they used before.
> ...

Sometimes there is a better solution.

> As I wrote before, it breaks the interface that is already established. Of course you can break it, but then you can't also be surprised if users complain.

I am not surprised, just disappointed at the quality of discourse.
October 27, 2023
On 10/27/23 16:35, Imperatorn wrote:
> If you don't use it, then you won't have a problem with it.

You are changing the topic here, but if a feature is going to be added, I'd rather have it be one I'd use reasonably often.
October 27, 2023
On 27/10/23 16:38, Imperatorn wrote:
>     It's funny to see people defending interpolated strings shouldn't be
>     string
> 
> I didn't think this level of comedy existed, but it seems we have reached a new level of existence.
> 
> I tried giving this conversation to GPT but it said "I'm sorry, the content you provided is to surreal, it cannot be captured in this plane of reality"
> 
> That's cool!
> 

As somebody who strongly supports making interpolated strings a drop-in replacement for strings, I think that, frustrating as it might feel, lowering the discourse doesn't help advance the argument.

It's better to show examples of where the feature as proposed would fall short of our, and I dare say most users', expectations.

From my side, I think I've already presented my arguments multiple times, so I will try to no rehearse them any more.
October 27, 2023

On Friday, 27 October 2023 at 14:16:01 UTC, Arafel wrote:

>

On 27/10/23 14:49, jmh530 wrote:

>

I tried to think of when I just want a string after doing interpolation (as opposed to writing immediately somehow) and struggled a bit.

I, on the other hand, do it constantly, especially when dealing with external libraries / systems.

Here is the first short and almost self-contained real-world example that I found having a quick look at my code. Just see how I construct and use mailOrder and input:

[snip]

Honestly, I don't see that much of an issue with .text, but I suppose I get that it would be an issue for new users. Personally, I would just do the template version of what you discussed and rejected, but if that's not for you, that's fine too.

One thing I considered was if you just are able to assign to a string if you don't use any formatting, but I think that leads to confusion as well. Either you go all the way or you don't.