December 16, 2019
On Monday, 16 December 2019 at 14:02:17 UTC, aliak wrote:
> On Monday, 16 December 2019 at 13:22:45 UTC, Atila Neves wrote:
>> On Monday, 16 December 2019 at 10:48:51 UTC, aliak wrote:
>>> On Monday, 16 December 2019 at 01:35:51 UTC, Walter Bright wrote:
>>>> On 12/15/2019 2:17 AM, Aliak wrote:
>>>>> To use it people will need to understand how to use d tuples as well.
>>>>
>>>> No, they don't.
>>>
>>> User: why can't I do this?/Why doesn't this work?
>>>
>>> string s = i"$var";
>>>
>>> Answer?
>>
>> import std.format: format;
>> string s = format(i"$var");
>
> This is non obvious. And only explainable by mentioning tuples.

In other words. You didn't answer anything. You just told the user what to do with no explanation as to why that has to be done.
December 16, 2019
On Mon, Dec 16, 2019 at 11:00:34AM +0000, aliak via Digitalmars-d wrote: [...]
> I'm starting to wonder now, what's the use case for returning tuples? Why not just a string?

For generating injection-proof SQL, for one thing.  Probably others.


T

-- 
GEEK = Gatherer of Extremely Enlightening Knowledge
December 16, 2019
On Monday, 16 December 2019 at 14:02:17 UTC, aliak wrote:
> On Monday, 16 December 2019 at 13:22:45 UTC, Atila Neves wrote:
>> On Monday, 16 December 2019 at 10:48:51 UTC, aliak wrote:
>>> On Monday, 16 December 2019 at 01:35:51 UTC, Walter Bright
>>> wrote:
>>>> On 12/15/2019 2:17 AM, Aliak wrote:
>>>>> To use it people will need to understand how to use d
>>>>> tuples as well.
>>>>
>>>> No, they don't.
>>>
>>> User: why can't I do this?/Why doesn't this work?
>>>
>>> string s = i"$var";
>>>
>>> Answer?
>>
>> import std.format: format;
>> string s = format(i"$var");
>
> This is non obvious. And only explainable by mentioning tuples.

It's worse than non-obvious: it's contrary to expectation. It's
something that docs are going to have to explain and justify.
It's something that people are going to want the compiler to
special case if only for a useful error message. And you get
the same problem in

  void greet(string name) {
      writeln("Hello, ", name);
  }

  void main(string[] args) {
      string title = "Mr.";
      greet(i"$title $(args[1])");
  }

Error: function myfirstdprogram.greet(string name) is not callable using argument types (string, string, string)

  // But I'm never calling greet with three strings? Why is it
  // saying the error is on a line with only one string?

It is, however, not that hard to explain and justify. That it
works for assigning the parameters is a little weird. That it
works for SQL is pretty cool. That it works for translation is,
actually, a very worthwhile innovation and a good reason to
keep the proposed behavior even if it's weird.

And 'tuples' in this sense do come up in other languages:

https://stackoverflow.com/questions/2322355/proper-name-for-python-operator

In terms of "reasons people get confused or doubtful and wander
away from D" I don't think it'll come anywhere close to someone
trying to make std.range and std.algorithm work while not
having a great understanding of how they're implemented or why.

Still, some way to at least auto-import and auto-use format()
would be nice (if adding to -betterC caveats). If functions
accepting a printf-style string just had a different type,

  extern(C) snprintf(scope char* s, size_t n, scope const ichar* format, ...);

then format() could be auto-invoked in string-typed i"" and you
get the benefits without the immediate blow to new users.

Of course then you have to justify all the different char
types, including combinations, whether idchar vs. dichar is the
valid one. It's gross, so I can understand why it's already
been mentioned and discarded as an option in the thread, but it
just seems inevitable that if DIP 1027 is added without some
kind of hack like this, that one will get added on later
anyway, after people keep complaining that D's interpolation
is wrong or weird.

December 16, 2019
On 12/14/19 8:21 PM, Walter Bright wrote:
> On 12/14/2019 6:47 AM, Steven Schveighoffer wrote:
>> What if the strings are all interpolated strings? e.g.:
>>
>> database.exec(i"UPDATE %table SET key=$key, value=${f}value "~
>>              i"WHERE index < ${d}index AND "~
>>              i"timestamp > ${D}lastTime");
> 
> 
> Then you'll get a tuple that looks like:
> 
>      "UPDATE %s SET key=%s, value=%f ", key, value, "WHERE index < %d AND ", index, "timestamp > %D", lastTime

Why? I mean concatenation of Tuples isn't defined to do anything.

pragma(msg, AliasSeq!("hello", "there") ~ AliasSeq!("world", "and everyone else"));

Error: incompatible types for (tuple("hello", "there")) ~ (tuple("world", "and everyone else")): both operands are of type (string, string)

But we could define it for interpolated string tuples to be the concatenation of the format strings followed by the AliasSeq of all the fields in order.

This is the time to make these decisions, because it will be hard to add later. Removing automatic string concatenation was a great addition, but took a long time to get into the language, due to not breaking existing code. I'd hate to have to do it again.

>> I actually think 'i' should be able to go before any string literal.
>> e.g.:
>>
>> iq{$a + $b}
>> i`$a + $b`
> 
> Since the other method works, I am striving to keep things as simple as possible. There needs to be very good reasons for gratuitous multiple ways of doing something, and I don't see one here.

I'm proposing you DON'T make the other method work (it doesn't now). There doesn't need to be multiple ways to do string literals. And in fact, concatenation of interpolated string literals (as proposed above) would work well to provide the most expressive power, as you could concatenate any style of interpolated literals together, just like you can for uninterpolated literals.

And it's not complicated. The postfix characters of `c`, `w`, and `d` do not warrant complicated explanations in the spec, and are usable on any of the string literal types. An `i` prefix is similar.

All that is needed is to say "if you put `i` in front of a string literal (any string literal) it becomes an interpolated string literal"

> Of course, then there's "what about qi strings", aaggghhhh.

That's not grammatically correct. It would be rejected. The "interpolated" property is orthogonal to the string literal method, and must come before it.

-Steve
December 16, 2019
On 12/16/2019 6:00 AM, Nick Treleaven wrote:
> On Monday, 16 December 2019 at 13:22:45 UTC, Atila Neves wrote:
>> On Monday, 16 December 2019 at 10:48:51 UTC, aliak wrote:
>>> User: why can't I do this?/Why doesn't this work?
>>>
>>> string s = i"$var";
>>>
>>> Answer?
>>
>> import std.format: format;
>> string s = format(i"$var");
> 
> That isn't an answer to the question, it's just a workaround. Interpolated strings could implicitly convert to strings, which is the most common use case in typical D code. That would not bloat code that doesn't need it, as Adam has shown by using an import inside a template.
> 
> Interpolated strings should not be designed with low-level concerns as the priority motivator at the cost of high level usability and safety.
> 
> D is supposed to be a type safe language, even std.format.format is not fully type safe because using string for a format string allows runtime errors.
> 
> Any good D interpolation proposal would support compile time checked format strings, even when runtime arguments are passed. D is supposed to be the best language for compile time stuff!

Having it go directly to a string has multiple problems:

1. Those who want the tuple in order to do something else with it will be unhappy and out of luck.

2. It will not work with betterC.

3. It will allocate GC memory.

4. It will be substantially slower because of the extra intermediate buffer.

5. I don't think it'll work with Steven Schweighoffer's SQL examples.

6. It will require the core language to depend on a rather large and complex Phobos routine.

7. It will not be any more typesafe than it would be generating a tuple.

8. The number of times I've wanted a formatted string as the end result, as opposed to wanting formatted insertion into something else, is about 1 in 100, if that.

December 16, 2019
On 12/11/19 4:52 AM, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review for DIP 1027, "String Interpolation":
> 
> https://github.com/dlang/DIPs/blob/148001a963f5d6e090bb6beef5caf9854372d0bc/DIPs/DIP1027.md 
> 
> 
> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on December 25, or when I make a post declaring it complete.
> 
> At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment.
> 
> Anyone intending to post feedback in this thread is expected to be familiar with the reviewer guidelines:
> 
> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
> 
> *Please stay on topic!*
> 
> Thanks in advance to all who participate.

Might I suggest we come up with a new name for this technique? I see there is going to be a lot of users who want true string interpolation, e.g.:

string str = i"My name is $name";

and be very confused that D string interpolation isn't like https://en.wikipedia.org/wiki/String_interpolation

Maybe something like "format tuple expansion" or "formatted interpolation"?

-Steve
December 16, 2019
On Monday, 16 December 2019 at 22:02:05 UTC, Steven Schveighoffer wrote:
> Might I suggest we come up with a new name for this technique?
> I see there is going to be a lot of users who want true string
> interpolation, e.g.:
>
> string str = i"My name is $name";
>
> and be very confused that D string interpolation isn't like
> https://en.wikipedia.org/wiki/String_interpolation
>
> Maybe something like "format tuple expansion" or "formatted
> interpolation"?
>
> -Steve

Programming language terminology is so random already that
this isn't going to help. Perl has 'hashes' and Python has
'dicts' and other languages have 'maps', but when I read about
AAs in D I just said "oh, hash tables" and mentally translated
all references from then on. People are going to do exactly the
same thing to "tuple expansion strings" and still complain that
"string interpolation in D" doesn't work as they expect.

But if it's called "tuple expansion strings", they'll *also*
complain about the weird name.

There might be some satisfaction in saying "you *should* have
expected something different because of the different name",
or in giving an explanation of the different name, but this
would all be a distraction from explaining why D's string
interpolation is different.

December 16, 2019
On Monday, 16 December 2019 at 22:12:37 UTC, mipri wrote:
> On Monday, 16 December 2019 at 22:02:05 UTC, Steven Schveighoffer wrote:
>> Might I suggest we come up with a new name for this technique?
>> I see there is going to be a lot of users who want true string
>> interpolation, e.g.:
>>
>> string str = i"My name is $name";
>>
>> and be very confused that D string interpolation isn't like
>> https://en.wikipedia.org/wiki/String_interpolation
>>
>> Maybe something like "format tuple expansion" or "formatted
>> interpolation"?
>>
>> -Steve
>
> Programming language terminology is so random already that
> this isn't going to help. Perl has 'hashes' and Python has
> 'dicts' and other languages have 'maps', but when I read about
> AAs in D I just said "oh, hash tables" and mentally translated
> all references from then on. People are going to do exactly the
> same thing to "tuple expansion strings" and still complain that
> "string interpolation in D" doesn't work as they expect.
>
> But if it's called "tuple expansion strings", they'll *also*
> complain about the weird name.
>
> There might be some satisfaction in saying "you *should* have
> expected something different because of the different name",
> or in giving an explanation of the different name, but this
> would all be a distraction from explaining why D's string
> interpolation is different.
The issue with user expectations should not be holding up on what to define for D. I checked today what other languages do and at least for kotlin. C#, scala, swift and 2 other there is nothing consistent of what interpolated strings are. In rust it is even more than a joke as they call interpolated normal C style format string.

So imo we should try to implement what fits the best the language and CT tuples is as D-ish as it gets.
December 16, 2019
On Monday, 16 December 2019 at 22:12:37 UTC, mipri wrote:
> but this
> would all be a distraction from explaining why D's string
> interpolation is different.

Here's some prose that I'd expect in a FAQ or tutorial.

---
* What do you mean, "it doesn't build strings"!?

i"$a $b $c" is translated to an argument list

  "%s %s %s", a, b, c

So it has no meaning outside of argument-passing.

* Why do that? No other language does that!

Those other languages also have some severe problems owing to
how they do string interpolation:

1. a universe of SQL injection and similar exploits, as it's
easy and convenient to build strings with interpolation even
though the underlying database APIs can accept arguments
separately and safely, with no need for ad-hoc 'sanitization'.

Well-written database code in these languages is therefore
written as if string interpolation is not a feature of the
language:

  $db->query("INSERT INTO names VALUES (?)", "Bob");

2. internationalization is defeated, as the structure of the
string that variables are interpolated into is lost. Invariably
as programs get international their developers have to comb
through the code base and remove uses of string interpolation:

  print("Hello, $name!");

  # is corrected to:

  printf(gettext("Hello, %s!"), name);

where gettext() might look up "Hello, %s" in a
translator-maintained table of greetings, to substitute
"Bonjour, %s".

In D, string interpolation is convenient for the simplest
tasks, and D is unusual in that string interpolation *remains*
convenient as tasks get more serious.

This comes at the small cost of having to pass an interpolated
string to a string-building function, like std.format's format,
if that's what you want.

  string s1 = i"Hello, $name!"; // error

  string s2 = i"Hello, $name!".format; // this is fine

  string s3 = format("Hello, %s!", name); // without i""
---

Even if the intended purpose is working with C-style printf()
functions, I'd highlight this use of i"" in a C interface or
BetterC section.
December 16, 2019
On Monday, 16 December 2019 at 22:33:57 UTC, Patrick Schluter wrote:
> what to define for D. I checked today what other languages do and at least for kotlin. C#, scala, swift and 2 other there is nothing consistent of what interpolated strings are.

Not sure what you mean by this, I find popular languages to be remarkably consistent.

Python:
    f"Three = {1 +2 }"

C#:
    $"Three = {1+2}"

TypeScript:
     `Three = ${1 + 2}`

Swift:
    "Three = \(1+2)"