www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [OT] C# can do all the interpolated strings now

reply WebFreak001 <d.forum webfreak.org> writes:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings


 compiler checks if the interpolated string is assigned to a 
 type that satisfies the interpolated string handler pattern
Usage example: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler What do you think of these extended interpolated string expressions? I think these would fit well into D, and could give some new motivation now that we have had our interpolated strings DIPs rejected once and withdrawn once.
Dec 08 2021
next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 wrote:
 give some new motivation now that we have had our interpolated 
 strings DIPs rejected once and withdrawn once.
there's another good document mostly written but waiting on john and andrei to take the next step.........
Dec 08 2021
parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 8 December 2021 at 12:55:02 UTC, Adam D Ruppe wrote:
 there's another good document mostly written but waiting on 
 john and andrei to take the next step.........
https://github.com/John-Colvin/YAIDIP
Dec 08 2021
next sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Wednesday, 8 December 2021 at 13:28:33 UTC, Dennis wrote:
 On Wednesday, 8 December 2021 at 12:55:02 UTC, Adam D Ruppe 
 wrote:
 there's another good document mostly written but waiting on 
 john and andrei to take the next step.........
https://github.com/John-Colvin/YAIDIP
ah yeah I couldn't remember where that one was, I only found the 2 other DIPs while googling. I like the overall idea but there is one thing that feels a little bad with that: If I have a function ```d void foo(string header, string docs); ``` I can't just pass ```d foo(i"$name's Website", i"Welcome on $name's Website"); ``` because interpolated strings are not strings. I would need an extra .text call. I think it would be easier on users if it was all one big struct like `InterpolatedString!(args here...)` - not being able to be multiple arguments at once Otherwise if you had `void foo(T...)(T args)` you could no longer iterate over every argument individually, but need to keep track of state to know whether you are in an interpolated string. (and you don't know when it ends)
Dec 08 2021
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/8/21 10:39 AM, WebFreak001 wrote:
 On Wednesday, 8 December 2021 at 13:28:33 UTC, Dennis wrote:
 On Wednesday, 8 December 2021 at 12:55:02 UTC, Adam D Ruppe wrote:
 there's another good document mostly written but waiting on john and 
 andrei to take the next step.........
https://github.com/John-Colvin/YAIDIP
ah yeah I couldn't remember where that one was, I only found the 2 other DIPs while googling. I like the overall idea but there is one thing that feels a little bad with that: If I have a function ```d void foo(string header, string docs); ``` I can't just pass ```d foo(i"$name's Website", i"Welcome on $name's Website"); ``` because interpolated strings are not strings. I would need an extra .text call.
I think as long as the call to default-interpolate to a string is somewhere at hand (like in object.d), then it's already a win. My current problem with the status quo is not just that I have to reformat the string to have ugly printf style codes in it, but that I also have to now add an import somewhere.
 I think it would be easier on users if it was all one big struct like 
 `InterpolatedString!(args here...)` - not being able to be multiple 
 arguments at once
Being a struct means it has to copy the data, which may not be desirable.
 Otherwise if you had `void foo(T...)(T args)` you could no longer 
 iterate over every argument individually, but need to keep track of 
 state to know whether you are in an interpolated string. (and you don't 
 know when it ends)
You do, because the first parameter tells you. https://github.com/John-Colvin/YAIDIP#the-interpolation-header -Steve
Dec 08 2021
prev sibling parent reply kdevel <kdevel vogtner.de> writes:
On Wednesday, 8 December 2021 at 13:28:33 UTC, Dennis wrote:
 On Wednesday, 8 December 2021 at 12:55:02 UTC, Adam D Ruppe 
 wrote:
 there's another good document mostly written but waiting on 
 john and andrei to take the next step.........
https://github.com/John-Colvin/YAIDIP
Does Dlang now support SQL injection? Quotes from https://github.com/John-Colvin/YAIDIP: ``` void f2(string name) { auto rows = sql("SELECT * FROM t WHERE name = ?", name); // specifier is a question mark ... } ```` This is an SQL query written lege artis. It enables the sql function to do whatever is necessary to perform the request without unwanted "side effects". Further down we must read this: ``` void main(string[] args) { import std.stdio; writeln(i"The program $(args[0]) received $(args.length - 1) arguments."); // Lowering: ---> // writeln(InterpolationHeader!("The program ", "args[0]", " received ", "args.length - 1", " arguments.")(), // "The program ", args[0], " received ", args.length - 1, " arguments."); auto s = sqlExec(i"INSERT INTO runs VALUES ($(args[0]), $(args.length - 1))"); // Lowering: ---> // auto s = sqlExec(InterpolationHeader!("INSERT INTO runs VALUES(", "args[0]", ", ", "args.length - 1", ")")(), // args[0], $(args.length - 1)); } ``` How is the proper separation of code (query) and data achieved in this case? To me auto argsmaxidx = args.length - 1; auto s = sqlExec("INSERT INTO runs VALUES (?, ?)", args [0], argsmaxidx); appears way more readable.
Dec 08 2021
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/8/21 4:31 PM, kdevel wrote:
 Further down we must read this:
 
 ```
 void main(string[] args) {
      import std.stdio;
      writeln(i"The program $(args[0]) received $(args.length - 1) 
 arguments.");
      // Lowering: --->
      // writeln(InterpolationHeader!("The program ", "args[0]", " 
 received ", "args.length - 1", " arguments.")(),
      //     "The program ", args[0], " received ", args.length - 1, " 
 arguments.");
 
      auto s = sqlExec(i"INSERT INTO runs VALUES ($(args[0]), 
 $(args.length - 1))");
      // Lowering: --->
      // auto s = sqlExec(InterpolationHeader!("INSERT INTO runs 
 VALUES(", "args[0]", ", ", "args.length - 1", ")")(),
      //    args[0], $(args.length - 1));
 }
 ```
 
 How is the proper separation of code (query) and data achieved in this 
 case?
Because the `sqlExec` function figures it out based on the interpolation header. It can tell which parts were literal strings, and which parts were interpolation parameters. The interpolation parameters are replaced with "?", and then the parameters are passed as data (to avoid SQL injection as expected).
 
 To me
 
     auto argsmaxidx = args.length - 1;
     auto s = sqlExec("INSERT INTO runs VALUES (?, ?)", args [0], 
 argsmaxidx);
 
 appears way more readable.
Both are readable, though I'd argue that for this particular example, the usage of `$(expr)` for syntax makes things complex to read (syntax highlighting should help). In our DIP we used ${expr}, which for SQL would be more readable, but might look worse for things like code mixins. But there are plenty of examples where the string-blueprint form is less readable (the INSERT form where you specify fields first, and then parameters later is kind of a terrible syntax to begin with). e.g. (from a real line of code in my codebase): ```d conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = ?", loc_latitude, loc_longitude, id); // compare to: conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, loc_lon = $loc_longitude WHERE id = $id"); ``` -Steve
Dec 08 2021
next sibling parent zjh <fqbqrr 163.com> writes:
On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven 
Schveighoffer wrote:

```d
 conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, 
 loc_lon = $loc_longitude WHERE id = $id");
``` I like it.
Dec 08 2021
prev sibling next sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven 
Schveighoffer wrote:
 On 12/8/21 4:31 PM, kdevel wrote:
 [...]
Both are readable, though I'd argue that for this particular example, the usage of `$(expr)` for syntax makes things complex to read (syntax highlighting should help). In our DIP we used ${expr}, which for SQL would be more readable, but might look worse for things like code mixins. But there are plenty of examples where the string-blueprint form is less readable (the INSERT form where you specify fields first, and then parameters later is kind of a terrible syntax to begin with). e.g. (from a real line of code in my codebase): ```d conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = ?", loc_latitude, loc_longitude, id); // compare to: conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, loc_lon = $loc_longitude WHERE id = $id"); ``` -Steve
I wonder why are most languages using $ or {}? What's the advantage over `\(...)`? With `\` we have the advantage of not reserving another special character in strings - we already use `\`! It'd be fully backwards compatible even without the i prefix. Swift does this too.
Dec 08 2021
next sibling parent bauss <jj_1337 live.dk> writes:
On Thursday, 9 December 2021 at 07:47:40 UTC, WebFreak001 wrote:
 On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven 
 Schveighoffer wrote:
 On 12/8/21 4:31 PM, kdevel wrote:
 [...]
Both are readable, though I'd argue that for this particular example, the usage of `$(expr)` for syntax makes things complex to read (syntax highlighting should help). In our DIP we used ${expr}, which for SQL would be more readable, but might look worse for things like code mixins. But there are plenty of examples where the string-blueprint form is less readable (the INSERT form where you specify fields first, and then parameters later is kind of a terrible syntax to begin with). e.g. (from a real line of code in my codebase): ```d conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = ?", loc_latitude, loc_longitude, id); // compare to: conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, loc_lon = $loc_longitude WHERE id = $id"); ``` -Steve
I wonder why are most languages using $ or {}? What's the advantage over `\(...)`? With `\` we have the advantage of not reserving another special character in strings - we already use `\`! It'd be fully backwards compatible even without the i prefix. Swift does this too.
I think it's because the idea for interpolated strings evolved from template engines / perl's variable interpolation (which sort of is string interpolation) where syntaxes for values etc. are commonly using {x} {{x}} $x etc. So it's probably just to keep it similar to that, as those are familiar syntaxes and has been through decades. Doesn't mean it's the best or can't be improved, but sometimes introducing new syntaxes etc. also introduces new complexities and additional learning curve.
Dec 09 2021
prev sibling next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 07:47:40 UTC, WebFreak001 wrote:
 I wonder why are most languages using $ or {}? What's the 
 advantage over `\(...)`?
```$``` is a historical variable prefix, dates back to BASIC and shell scripting languages, so basically back to the 60s and 70s. It makes variable-substitution stand out visually. ```{}``` is really the best "mnemonic" as it signifies a chunk of executed code, so from a usability perspective that is the best option. Then you can use ```{{``` for escape. People who love string mixins probably disagree… I don't like backslashes for common escapes, makes code harder to read. Anyone that has spent a significant amount of time debugging long regex's can attest to that. The backslash is used for so many other escapes in strings and custom string notations that it does not stand out as much.
Dec 09 2021
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 2:47 AM, WebFreak001 wrote:
 I wonder why are most languages using $ or {}? What's the advantage over 
 `\(...)`?
I've used the swift syntax, and I don't like it as much. It looks somewhat clunky. Though, really, this is just asthetics.
 
 With `\` we have the advantage of not reserving another special 
 character in strings - we already use `\`! It'd be fully backwards 
 compatible even without the i prefix.
There are significant problems there though. The intention of the string interpolation DIPs so far is not necessarily to generate strings but to give a mechanism to overload for string interpolations. So the `i""` type is different than `""` on purpose. Also, other string types do not have escape sequences. -Steve
Dec 09 2021
prev sibling next sibling parent reply kdevel <kdevel vogtner.de> writes:
On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven 
Schveighoffer wrote:
 On 12/8/21 4:31 PM, kdevel wrote:
[...]
 How is the proper separation of code (query) and data achieved 
 in this case?
Because the `sqlExec` function figures it out based on the interpolation header. It can tell which parts were literal strings, and which parts were interpolation parameters.
So the string interpolation is used to emulate something like embedded SQL (ESQL) with the exception that the (SQL) code is quoted. ESQL looks like this [1]: ``` EXEC SQL INSERT INTO tablename VALUES (:variablename); ``` This is clearly favorable over embedded question marks plus argument lists.
 The interpolation parameters are replaced with "?", and then 
 the parameters are passed as data (to avoid SQL injection as 
 expected).
I missed that part. [...]
 e.g. (from a real line of code in my codebase):

 ```d
 conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? 
 WHERE id = ?", loc_latitude, loc_longitude, id);

 // compare to:
 conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, 
 loc_lon = $loc_longitude WHERE id = $id");
 ```
Final questions: What happens if the "i" in front of the string is accidentally lost? Compile-time oder runtime error? How does the compiler/runtime know which type of interpolation to choose? I mean if you have ``` conn.exec (i"UPDATE organization SET loc_lat = $loc_latitude... html.output (i"<input value=\"$value\" ... ``` how and where is decided to use the SQL interpolation in the first and the HTML escaping in the second line? What is the return type of the interpolation? Stefan [1] https://en.wikipedia.org/wiki/ECPG#Using_host_variables PS: The following code snippet is from the YAIDIP document: ``` executeShell("wget " ~ url ~ " -O" ~ file ~ ".frag && mv " ~ file ~ ".frag " ~ file); ``` That should not have been written in the first place. This code is prone to shell injection and the only shell-specific functionality is that of the "&&". Long story short: I would have written it that way: ``` execute(["wget", url, "-O", file ~ ".frag"]).status == 0 && execute(["mv", file ~ ".frag ", file]); ```
Dec 09 2021
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 9:33 AM, kdevel wrote:
 On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven Schveighoffer wrote:
 On 12/8/21 4:31 PM, kdevel wrote:
[...]
 How is the proper separation of code (query) and data achieved in 
 this case?
Because the `sqlExec` function figures it out based on the interpolation header. It can tell which parts were literal strings, and which parts were interpolation parameters.
So the string interpolation is used to emulate something like embedded SQL (ESQL) with the exception that the (SQL) code is quoted. ESQL looks like this [1]: ```    EXEC SQL INSERT INTO tablename VALUES (:variablename); ``` This is clearly favorable over embedded question marks plus argument lists.
Yes, this is the biggest point of the DIPs that have been introduced so far -- put the parameters in context.
 
 The interpolation parameters are replaced with "?", and then the 
 parameters are passed as data (to avoid SQL injection as expected).
I missed that part.
It might be implied and not specifically spelled out (I don't know, I read the DIP a long time ago).
 
 [...]
 
 e.g. (from a real line of code in my codebase):

 ```d
 conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = 
 ?", loc_latitude, loc_longitude, id);

 // compare to:
 conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, loc_lon = 
 $loc_longitude WHERE id = $id");
 ```
Final questions: What happens if the "i" in front of the string is accidentally lost? Compile-time oder runtime error?
It depends. If `conn.exec` accepts a standard `string`, then it's a runtime error -- without the i, the string is just a string, which contains the literal data with `$loc_latitude`, etc. which the SQL server doesn't understand. This is similar to what happens when you do (as I often do): `writeln("%s: %s", name, value);` If `conn.exec` only accepts interpolated literals, then it's a compile time error.
 How does the compiler/runtime know which type of interpolation to 
 choose? I mean if you have
 
 ```
     conn.exec (i"UPDATE organization SET loc_lat = $loc_latitude...
     html.output (i"<input value=\"$value\" ...
 ```
 
 how and where is decided to use the SQL interpolation in the first and 
 the HTML escaping in the second line?
That is the beauty of this proposal! The parameters are simply passed as-is into the function. If the function accepts them properly, it gets to decide how to handle it. html.output can do whatever it wants differently than conn.exec.
 
 What is the return type of the interpolation?
There isn't one. The interpolation is not a function, it's a literal that expands into a parameter list.
 
 PS: The following code snippet is from the YAIDIP document:
 
 ```
     executeShell("wget " ~ url ~ " -O" ~ file ~ ".frag && mv " ~ file ~ 
 ".frag " ~ file);
 ```
 
 That should not have been written in the first place. This code is prone 
 to shell injection and the only shell-specific functionality is that of 
 the "&&". Long story short: I would have written it that way:
 
 ```
     execute(["wget", url, "-O", file ~ ".frag"]).status == 0
     &&
     execute(["mv", file ~ ".frag ", file]);
 ```
 
Yeah, it might not explicitly state that the original code is subject to injection, but the interpolated version has the *potential* to avoid it, whereas the original snippet has no chance. -Steve
Dec 09 2021
prev sibling parent reply forkit <forkit gmail.com> writes:
On Wednesday, 8 December 2021 at 22:10:32 UTC, Steven 
Schveighoffer wrote:
 But there are plenty of examples where the string-blueprint 
 form is less readable (the INSERT form where you specify fields 
 first, and then parameters later is kind of a terrible syntax 
 to begin with).

 e.g. (from a real line of code in my codebase):

 ```d
 conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? 
 WHERE id = ?", loc_latitude, loc_longitude, id);

 // compare to:
 conn.exec(i"UPDATE organization SET loc_lat = $loc_latitude, 
 loc_lon = $loc_longitude WHERE id = $id");
 ```

 -Steve
Well, for me, the first example you presented is so much more readable: i.e. conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = ?", loc_latitude, loc_longitude, id); My brain straight away looks for that comma, and I immediately see what the parameters are. The other way, I have to read and parse the ENTIRE string!
Dec 09 2021
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 5:42 PM, forkit wrote:

 Well, for me, the first example you presented is so much more readable:
 
 i.e.
 
 conn.exec("UPDATE organization SET loc_lat = ?, loc_lon = ? WHERE id = 
 ?", loc_latitude, loc_longitude, id);
 
 My brain straight away looks for that comma, and I immediately see what 
 the parameters are.
Which comma? there are commas in the string too. You have to parse the string first to find the right comma.
 The other way, I have to read and parse the ENTIRE string!
So you just ignore the string? What if there are parameter mismatches? -Steve
Dec 09 2021
parent reply forkit <forkit gmail.com> writes:
On Friday, 10 December 2021 at 01:00:57 UTC, Steven Schveighoffer 
wrote:
 Which comma? there are commas in the string too. You have to 
 parse the string first to find the right comma.
The first comma after the string. I don't even think. My brain takes me straight there, automatically (seemingly without parsing the string). Whatever thinking my brain does, it is not apparent to me ;-)
 So you just ignore the string? What if there are parameter 
 mismatches?

 -Steve
That's an extra task to be undertaken, if needed. e.g. say you have to change one or more of your parameter names (but don't need to change their order). Well, it's much easier NOT to be forced to parse an entire interpolated string. There are pro's and con's, I accept that. But having done without interpolated strings, for decades, I don't see the point of introducing them, and then having to deal with TWO different ways to achieve the exact same outcome.
Dec 09 2021
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 9:10 PM, forkit wrote:

 There are pro's and con's, I accept that. But having done without 
 interpolated strings, for decades, I don't see the point of introducing 
 them, and then having to deal with TWO different ways to achieve the 
 exact same outcome.
 
I guess then it comes down to which brain you have. My brain does not see the immediate correlation between disjoint string placeholders and parameter values. I have to look back and forth, especially with long SQL statements, counting question marks (often times some values are in the SQL string and not parameters). To each his own, and fortunately, we can have both ways! -Steve
Dec 09 2021
parent forkit <forkit gmail.com> writes:
On Friday, 10 December 2021 at 02:32:32 UTC, Steven Schveighoffer 
wrote:
 I guess then it comes down to which brain you have. My brain 
 does not see the immediate correlation between disjoint string 
 placeholders and parameter values. I have to look back and 
 forth, especially with long SQL statements, counting question 
 marks (often times some values are in the SQL string and not 
 parameters).

 To each his own, and fortunately, we can have both ways!

 -Steve
but if there were only one way, it would not matter which brain we had, as it would be doing exactly the same thing. with both ways, it's even worse, as your brain, and mine, now need to know how to do both. In the end, what is really achieved? -> Just added complexity.
Dec 09 2021
prev sibling next sibling parent reply bachmeier <no spam.net> writes:
On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 wrote:
 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings


 compiler checks if the interpolated string is assigned to a 
 type that satisfies the interpolated string handler pattern
Usage example: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler What do you think of these extended interpolated string expressions? I think these would fit well into D, and could give some new motivation now that we have had our interpolated strings DIPs rejected once and withdrawn once.
I'm not gonna judge anyone, but `System.Runtime.CompilerServices.DefaultInterpolatedStringHandler` might be classified by some as verbose.
Dec 08 2021
parent bauss <jj_1337 live.dk> writes:
On Wednesday, 8 December 2021 at 13:51:53 UTC, bachmeier wrote:
 On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 
 wrote:
 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings


 the compiler checks if the interpolated string is assigned to 
 a type that satisfies the interpolated string handler pattern
Usage example: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler What do you think of these extended interpolated string expressions? I think these would fit well into D, and could give some new motivation now that we have had our interpolated strings DIPs rejected once and withdrawn once.
I'm not gonna judge anyone, but `System.Runtime.CompilerServices.DefaultInterpolatedStringHandler` might be classified by some as verbose.
Well in theory you only need to type DefaultInterpolatedStringHandler if you have a using statement in top of your file like "using System.Runtime.CompilerServices;".
Dec 08 2021
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/8/21 5:46 AM, WebFreak001 wrote:
 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-
nterpolated-strings 
 
 

 compiler checks if the interpolated string is assigned to a type that 
 satisfies the interpolated string handler pattern
Usage example: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpo ated-string-handler What do you think of these extended interpolated string expressions? I think these would fit well into D, and could give some new motivation now that we have had our interpolated strings DIPs rejected once and withdrawn once.
No, I think the interpolation tuples that Adam and I proposed, and the proposal from John and Andrei are much simpler and straightforward. "We introduce a new handler pattern that can represent an interpolated string passed as an argument to a method. The simple English of the pattern is as follows: When an interpolated_string_expression is passed as an argument to a method, we look at the type of the parameter. If the parameter type has a constructor that can be invoked with 2 int parameters, literalLength and formattedCount, optionally takes additional parameters specified by an attribute on the original parameter, optionally has an out boolean trailing parameter, and the type of the original parameter has instance AppendLiteral and AppendFormatted methods that can be invoked for every part of the interpolated string, then we lower the interpolation using that, instead of into a traditional call to string.Format(formatStr, args)." Ugh... -Steve
Dec 08 2021
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 wrote:
 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings


 compiler checks if the interpolated string is assigned to a 
 type that satisfies the interpolated string handler pattern
Usage example: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler What do you think of these extended interpolated string expressions? I think these would fit well into D, and could give some new motivation now that we have had our interpolated strings DIPs rejected once and withdrawn once.
this. So I read the proposal for string interpolation in D, which I understand to be this one: https://github.com/John-Colvin/YAIDIP The immediate thing that stroke me is the shell example. The proposed exemple is simply terrible code as it allows for shell injection. One of the motivating example is SQL prepared statements, but once again, replacing this by the proposed string interpolation means SQL injection. In its current form, I'm not convinced the current proposal is something we want. If this reaches any kind of scale, this will inevitably end up as a forbidden language construct in a linter.
Dec 09 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 10:43:07 UTC, deadalnix wrote:
 In its current form, I'm not convinced the current proposal is 
 something we want. If this reaches any kind of scale, this will 
 inevitably end up as a forbidden language construct in a linter.
What I don't understand is why meta-programming isn't strengthened instead so that string interpolation can be implemented as a library construct. If you then put it in the standard library compilers can recognize it and optimize for it. You basically need: 1. custom literals (seek inspiration in C++) 2. some limited AST rewriting capabilities. That would also make it much easier to write DSLs. D needs to hunker down on meta-programming and not spread itself thin across the feature-set of other languages. There is also no universal syntax for interpolation that works in all contexts. E.g. in regexes many symbols will be confusing, in complicated strings with many sigils you want substitution to stand out (which is why Angular uses ```{{…}}```). In a DSL you can also have much safer and more convenient interpolation, e.g. a SQL DSL could check that tables exists in a model at compile time or something to that effect. Bring custom verification of string-literals by adding user defined literals instead. D really needs to stop running after other languages and instead bring unique benefits to programmers, based on meta-programming.
Dec 09 2021
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 9 December 2021 at 10:43:07 UTC, deadalnix wrote:
 So I read the proposal for string interpolation in D, which I 
 understand to be this one: https://github.com/John-Colvin/YAIDIP

 The immediate thing that stroke me is the shell example. The 
 proposed exemple is simply terrible code as it allows for shell 
 injection.
You say you read it, then say something that is blatantly false about it. This dip does NOT produce strings. It produces argument lists. The receiving function knows what was part of the string literal and what were arguments and can process them accordingly.
Dec 09 2021
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 12:43:31 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 10:43:07 UTC, deadalnix wrote:
 So I read the proposal for string interpolation in D, which I 
 understand to be this one: 
 https://github.com/John-Colvin/YAIDIP

 The immediate thing that stroke me is the shell example. The 
 proposed exemple is simply terrible code as it allows for 
 shell injection.
You say you read it, then say something that is blatantly false about it. This dip does NOT produce strings. It produces argument lists. The receiving function knows what was part of the string literal and what were arguments and can process them accordingly.
But don't you think it would be better if you could write: ``` sql"SELECT x,y,z FROM {something} FROM {condition}" ``` Then have a user provided custom compile time function check the string and wrap ```something``` and ```condition``` with the proper escape-functions. Then you could pass it anywhere you want as a properly typed SqlStatement. All you need is something like: ``` SqlStatement string_interpolation(string!"sql" s){ … } ``` Which is called when a ```sql"…"``` literal fails to convert, that allows libraries to override the default ```string_interpolation```. You could let ```string!"sql"``` be a subtype of ```string``` for ease of use. Just one possibility that is much more flexible and safer as it actually is *typed*. D should aim for generic programming within the current framework, not add new weird special cases (tuples are bad enough, no need to have more of that).
Dec 09 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim Grøstad 
wrote:
 Which is called when a ```sql"…"``` literal fails to convert, 
 that allows libraries to override the default 
 ```string_interpolation```.
Didn't mean convert, meant *bind to parameters*. E.g. ```void myfunc(string!"sql" s)``` would take precedence over ```string_interpolate```.
Dec 09 2021
prev sibling next sibling parent reply mork <mork mork.mork> writes:
On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 9 December 2021 at 12:43:31 UTC, Adam D Ruppe 
 wrote:
 [...]
But don't you think it would be better if you could write: [...]
auto sqlstring = sql!i"SELECT x,y,z FROM {something} FROM {condition}";
Dec 09 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 13:07:20 UTC, mork wrote:
 auto sqlstring = sql!i"SELECT x,y,z FROM {something} FROM 
 {condition}";
A bit clunky. With a custom interpolation function you could overload on the return type and have domain specific syntax.
Dec 09 2021
parent reply Kagamin <spam here.lot> writes:
On Thursday, 9 December 2021 at 13:27:06 UTC, Ola Fosheim Grøstad 
wrote:
 A bit clunky. With a custom interpolation function you could 
 overload on the return type and have domain specific syntax.
DSLs are already possible with template mixins in a clean form without sigils.
Dec 09 2021
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 14:04:18 UTC, Kagamin wrote:
 DSLs are already possible with template mixins in a clean form 
 without sigils.
You mean as string mixins?
Dec 09 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 14:13:58 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 9 December 2021 at 14:04:18 UTC, Kagamin wrote:
 DSLs are already possible with template mixins in a clean form 
 without sigils.
You mean as string mixins?
Just to clarify to avoid unnecessary discussion about what I wrote, as I might not have been specific enough: I am not suggesting the implementation of builtin string interpolation, but custom literals with conversion functions. It should probably not be called ```string_interpolation```, just ```convert``` or ``` convert```. This is different from string mixins as it would be more composable, overloadable, and with stronger typing and no ```mixin```. It should work for custom literals like ```100.34ms``` as well as ```sql"SELECT …"```. As such, you would integrate the "DSL" more with regular D-code than you do with string mixins. Basically: try to find a generic solution for custom literals that allows the implementation of string-interpolation.
Dec 09 2021
parent reply Kagamin <spam here.lot> writes:
On Thursday, 9 December 2021 at 14:30:33 UTC, Ola Fosheim Grøstad 
wrote:
 I am not suggesting the implementation of builtin string 
 interpolation, but custom literals with conversion functions. 
 It should probably not be called ```string_interpolation```, 
 just ```convert``` or ``` convert```.

 This is different from string mixins as it would be more 
 composable, overloadable, and with stronger typing and no 
 ```mixin```.
I looks like you propose string mixin with a different syntax. If behavior is customizable, you can't guarantee the custom handler will use a strong type system and provide all those features you want.
Dec 10 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 10 December 2021 at 08:26:38 UTC, Kagamin wrote:
 I looks like you propose string mixin with a different syntax. 
 If behavior is customizable, you can't guarantee the custom 
 handler will use a strong type system and provide all those 
 features you want.
Not sure what you mean by guarantee, it will enable stronger typing than the DIP for sure. If you want to force strong typing (not sure why) then you require a grammar to be associated with the string tag. This would also enable automatic string validation, auto completion in IDEs etc.
Dec 10 2021
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Thursday, 9 December 2021 at 14:04:18 UTC, Kagamin wrote:
 On Thursday, 9 December 2021 at 13:27:06 UTC, Ola Fosheim 
 Grøstad wrote:
 A bit clunky. With a custom interpolation function you could 
 overload on the return type and have domain specific syntax.
DSLs are already possible with template mixins in a clean form without sigils.
No, there are identifier resolution problems. It's like we don't want macro, so we reinvent 20 bad versions of them in the effort of not implementing them.
Dec 09 2021
parent Kagamin <spam here.lot> writes:
On Thursday, 9 December 2021 at 16:16:58 UTC, deadalnix wrote:
 On Thursday, 9 December 2021 at 14:04:18 UTC, Kagamin wrote:
 On Thursday, 9 December 2021 at 13:27:06 UTC, Ola Fosheim 
 Grøstad wrote:
 A bit clunky. With a custom interpolation function you could 
 overload on the return type and have domain specific syntax.
DSLs are already possible with template mixins in a clean form without sigils.
No, there are identifier resolution problems. It's like we don't want macro, so we reinvent 20 bad versions of them in the effort of not implementing them.
That's what L stands for in DSL. As opposed to interpolated string, DSL has semantics, which can inform identifier resolution.
Dec 10 2021
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim Grøstad 
wrote:
 But don't you think it would be better if you could write:
No.
Dec 09 2021
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 13:24:14 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim 
 Grøstad wrote:
 But don't you think it would be better if you could write:
No.
How is: ```sql(i"SELECT $(r[0]), $(r[3]), FROM $(t[3]) WHERE $(c[6])")``` An improvement over: ```sql("SELECT", r[0], r[3], "FROM", t[3], "WHERE", c[6])``` ? It obviously isn't! This will end up being a marginal feature.
Dec 09 2021
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 8:50 AM, Ola Fosheim Grøstad wrote:
 On Thursday, 9 December 2021 at 13:24:14 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim Grøstad wrote:
 But don't you think it would be better if you could write:
No.
How is: ```sql(i"SELECT $(r[0]), $(r[3]), FROM $(t[3]) WHERE $(c[6])")``` An improvement over: ```sql("SELECT", r[0], r[3], "FROM", t[3], "WHERE", c[6])``` ? It obviously isn't!
What is that sql function doing? It's not just concatenating strings, and it's also not anything I would ever want to use, in original or interpolation form. It appears to suggest it's going to happily do sql injection as well.
 This will end up being a marginal feature.
For this fictitious example, maybe. But I already see huge potential in my real actual libraries that I've written. You don't have to use it if you don't want to. -Steve
Dec 09 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 14:25:10 UTC, Steven 
Schveighoffer wrote:
 What is that sql function doing? It's not just concatenating 
 strings, and it's also not anything I would ever want to use, 
 in original or interpolation form. It appears to suggest it's 
 going to happily do sql injection as well.
Well, the DIP does not propose string building, it is basically string-splitting with a bit of mixin… (kinda) Anyway, you could define constants for SELECT, FROM and WHERE and get even better syntax: ```sql(SELECT, r[0], r[3], FROM, t[3], WHERE, c[6])``` Then let sql escape-wrap the parameters.
 For this fictitious example, maybe. But I already see huge 
 potential in my real actual libraries that I've written.
Ok, but maybe you could write even better libraries if D added custom literals instead? :-)
 You don't have to use it if you don't want to.
True, I don't use string interpolation in JavaScript much either. I use it everywhere in Python. The details matters a lot for it to increase readability. I just wish D would focus more on providing generic solutions than N narrow special cases. I think these special cases are pushed in because people in the forums are too impatient to wait for the emergence of a generic solution. Understandable, but not good for the compiler/language over time.
Dec 09 2021
prev sibling parent deadalnix <deadalnix gmail.com> writes:
On Thursday, 9 December 2021 at 13:24:14 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim 
 Grøstad wrote:
 But don't you think it would be better if you could write:
No.
Ola's direction does compose much better.
Dec 09 2021
prev sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Thursday, 9 December 2021 at 13:03:21 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 9 December 2021 at 12:43:31 UTC, Adam D Ruppe 
 wrote:
 On Thursday, 9 December 2021 at 10:43:07 UTC, deadalnix wrote:
 So I read the proposal for string interpolation in D, which I 
 understand to be this one: 
 https://github.com/John-Colvin/YAIDIP

 The immediate thing that stroke me is the shell example. The 
 proposed exemple is simply terrible code as it allows for 
 shell injection.
You say you read it, then say something that is blatantly false about it. This dip does NOT produce strings. It produces argument lists. The receiving function knows what was part of the string literal and what were arguments and can process them accordingly.
But don't you think it would be better if you could write: ``` sql"SELECT x,y,z FROM {something} FROM {condition}" ``` [...]
Love the idea of having type-safety with this! JS has similar syntax with `` sql`...` `` where it will call the function `sql` with the parts of the interpolated string. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Dec 09 2021
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 9:25 AM, WebFreak001 wrote:

 Love the idea of having type-safety with this! JS has similar syntax 
 with `` sql`...` `` where it will call the function `sql` with the parts 
 of the interpolated string.
 
 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referen
e/Template_literals 
 
This is exactly what the proposal is doing. But instead of using `sql` as a specialized prefix (you have to be careful with these, as adding arbitrary literal prefixes can mess up the grammar) it's just a parameter tuple, and you specify the function as normal. i.e. this is practically identical to: ```d sql(i"SELECT x,y,z FROM $something WHERE $condition"); ``` Or even: ```d i"SELECT x,y,z FROM $something WHERE $condition".sql; ``` -Steve
Dec 09 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 14:57:25 UTC, Steven 
Schveighoffer wrote:
 (you have to be careful with these, as adding arbitrary literal 
 prefixes can mess up the grammar)
(no)
Dec 09 2021
prev sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Thursday, 9 December 2021 at 14:57:25 UTC, Steven 
Schveighoffer wrote:
 On 12/9/21 9:25 AM, WebFreak001 wrote:

 Love the idea of having type-safety with this! JS has similar 
 syntax with `` sql`...` `` where it will call the function 
 `sql` with the parts of the interpolated string.
 
 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
 
This is exactly what the proposal is doing. But instead of using `sql` as a specialized prefix (you have to be careful with these, as adding arbitrary literal prefixes can mess up the grammar) it's just a parameter tuple, and you specify the function as normal. i.e. this is practically identical to: ```d sql(i"SELECT x,y,z FROM $something WHERE $condition"); ``` Or even: ```d i"SELECT x,y,z FROM $something WHERE $condition".sql; ``` -Steve
I think identifiers immediately followed by a string literal are unambiguous. Currently a syntax error, afterwards useful interpolation. The i"" proposal allows to pass multiple arguments at once, and with that adds new cases to the compiler that a single literal can be multiple arguments. The identifier + string literal stays within bounds of existing behavior. I think you would really really never want to pass these raw tuple values to any function other than to explicitly designed interpolated string handlers. Given that assumption I think it's safe to say the `i` prefix is redundant, and you should just always need to use a handler function. The identifier + string literal syntax elegantly does this without redundant syntax, it's familiar to JS programmers and it doesn't allow passing more than the interpolated string to handler functions or functions with variadic arguments. (which is a good thing) Samples: ```d sql(i"SELECT x,y,z FROM $something WHERE $condition") text(i"hello $name") mixin(i"class $name {}") ``` vs ```d i"SELECT x,y,z FROM $something WHERE $condition".sql i"hello $name".text mixin(i"class $name {}") // no equivalent ``` vs ```d sql"SELECT x,y,z FROM $something WHERE $condition" text"hello $name" mixin"class $name {}" ``` or have some kind of new function call punctuation: ```d sql$"SELECT x,y,z FROM $something WHERE $condition" text$"hello $name" mixin$"class $name {}" ``` --- and if you want to actually access the tuple for variadic template arguments (including the header) you could still do this: ```d AliasSeq"hello $name" ``` (or `alias I = AliasSeq;` and `I"hello $name"`)
Dec 09 2021
next sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Thursday, 9 December 2021 at 15:16:40 UTC, WebFreak001 wrote:
 On Thursday, 9 December 2021 at 14:57:25 UTC, Steven 
 Schveighoffer wrote:
 [...]

 i.e. this is practically identical to:

 ```d
 sql(i"SELECT x,y,z FROM $something WHERE $condition");
 ```

 Or even:

 ```d
 i"SELECT x,y,z FROM $something WHERE $condition".sql;
 ```

 -Steve
[...]
and I want to add, this is the super rare case: ```d foo(i"hello $name") ``` this is the much more common case: ```d foo(i"hello $name".text) // or foo(text(i"hello $name")) ``` I don't think the common case should always have this extra `i` prefix + needed function calling parentheses or ufcs dot. Just only writing `text"hello $name"` is shorter, easier to type, better to read.
Dec 09 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 15:20:42 UTC, WebFreak001 wrote:
 I don't think the common case should always have this extra `i` 
 prefix + needed function calling parentheses or ufcs dot. Just 
 only writing `text"hello $name"` is shorter, easier to type, 
 better to read.
Yes, in my experience I primarily use string interpolation when the API does not allow a comma-separated list. For instance if you throw an exception and there only is a message parameter. I guess one could say that string interpolation shines where it overcomes API limitations, but it has to be concise.
Dec 09 2021
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 10:20 AM, WebFreak001 wrote:
 On Thursday, 9 December 2021 at 15:16:40 UTC, WebFreak001 wrote:
 On Thursday, 9 December 2021 at 14:57:25 UTC, Steven Schveighoffer wrote:
 [...]

 i.e. this is practically identical to:

 ```d
 sql(i"SELECT x,y,z FROM $something WHERE $condition");
 ```

 Or even:

 ```d
 i"SELECT x,y,z FROM $something WHERE $condition".sql;
 ```
[...]
and I want to add, this is the super rare case: ```d foo(i"hello $name") ```
I disagree. I find that the non-rare case. This is what I'm looking for. The interesting case is not some specialized function that transforms the parameters into a string in a specific way, but one that accepts the parameters as-is and works with them directly.
 this is the much more common case:
 
 ```d
 foo(i"hello $name".text)
 // or
 foo(text(i"hello $name"))
 ```
In my original DIP, I tried to handle both cases, `foo(i"hello $name")` for `foo(string)` would work. It's a messy situation, and I think it's the reason there was so much opposition. Having to type `text` or whatever is a reasonable compromise.
 
 I don't think the common case should always have this extra `i` prefix + 
 needed function calling parentheses or ufcs dot. Just only writing 
 `text"hello $name"` is shorter, easier to type, better to read.
Note that the string interpolation proposal does not preclude this possibility happening later. Reasonable people can disagree whether this "makes the feature" or not though. -Steve
Dec 09 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 15:47:11 UTC, Steven 
Schveighoffer wrote:
 On 12/9/21 10:20 AM, WebFreak001 wrote:
 I don't think the common case should always have this extra 
 `i` prefix + needed function calling parentheses or ufcs dot. 
 Just only writing `text"hello $name"` is shorter, easier to 
 type, better to read.
Note that the string interpolation proposal does not preclude this possibility happening later.
You can fix this with implicit conversion to string, but it makes for weaker typing: 1. expand to list 2. if expanding to list fails type check then try to concatenate to string 3. if string does not pass type check, report error So, it is easy to fix without any extra ```.text``` annoyances.
Dec 09 2021
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 9 December 2021 at 15:55:42 UTC, Ola Fosheim Grøstad 
wrote:
 You can fix this with implicit conversion to string, but it 
 makes for weaker typing:
This has been discussed over many years. If you haven't read the previous DIPs and those too, you aren't contributing anything. It is a complete waste of time to go over this over and over and over and over and over and over again.
Dec 09 2021
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 16:02:19 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 15:55:42 UTC, Ola Fosheim 
 Grøstad wrote:
 You can fix this with implicit conversion to string, but it 
 makes for weaker typing:
This has been discussed over many years. If you haven't read the previous DIPs and those too,
I read the current DIP, I read some of the other DIPs a long time ago, no need to feel offended. I would not recommend weaker typing, as it would be trivial to get stronger typing by simply supporting ```f"this $will become a string"``` and ```i"this $will become a list"```. But if one is hellbent on having the DIP as stated you end up with something that is very unfriendly to newbies. It does not make the language more accessible. As enthusiasts you need to think a little bit further than your own perception of "good".
Dec 09 2021
next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 9 December 2021 at 16:30:28 UTC, Ola Fosheim Grøstad 
wrote:
 I would not recommend weaker typing, as it would be trivial to 
 get stronger typing
This is factually false.
 It does not make the language more accessible. As enthusiasts 
 you need to think a little bit further than your own perception 
 of "good".
Your objection has been noted and overruled. Good bye.
Dec 09 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 9 December 2021 at 16:32:11 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 16:30:28 UTC, Ola Fosheim 
 Grøstad wrote:
 I would not recommend weaker typing, as it would be trivial to 
 get stronger typing
This is factually false.
Nope.
Dec 09 2021
prev sibling parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 9 December 2021 at 16:30:28 UTC, Ola Fosheim Grøstad 
wrote:
 I would not recommend weaker typing, as it would be trivial to 
 get stronger typing by simply supporting ```f"this $will become 
 a string"``` and ```i"this $will become a list"```.
That would have the problem that confusing `i""` and `f""` could lead to SQL injections and related problems. The improvement over using `i"".text` is almost nonexistent.
Dec 12 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 12 December 2021 at 19:44:17 UTC, Q. Schroll wrote:
 On Thursday, 9 December 2021 at 16:30:28 UTC, Ola Fosheim 
 Grøstad wrote:
 I would not recommend weaker typing, as it would be trivial to 
 get stronger typing by simply supporting ```f"this $will 
 become a string"``` and ```i"this $will become a list"```.
That would have the problem that confusing `i""` and `f""` could lead to SQL injections and related problems. The improvement over using `i"".text` is almost nonexistent.
How could you confuse them? The type system would prevent it.
Dec 12 2021
parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Sunday, 12 December 2021 at 20:55:49 UTC, Ola Fosheim Grøstad 
wrote:
 On Sunday, 12 December 2021 at 19:44:17 UTC, Q. Schroll wrote:
 On Thursday, 9 December 2021 at 16:30:28 UTC, Ola Fosheim 
 Grøstad wrote:
 I would not recommend weaker typing, as it would be trivial 
 to get stronger typing by simply supporting ```f"this $will 
 become a string"``` and ```i"this $will become a list"```.
That would have the problem that confusing `i""` and `f""` could lead to SQL injections and related problems. The improvement over using `i"".text` is almost nonexistent.
How could you confuse them?
In cases like this, for example? ```D void func(string str); void func(Is...)(Is interpString) if (isInterpString!Is); string value = "bla"; func(f"some $bla bla"); // calls first one func(i"some $bla bla"); // calls second one ``` If I understand your suggestion correctly, both would compile, but be handled differently. It's a one-keystroke difference and people will conflate `i""` and `f""` for sure and it could lead to serious vulnerabilities. Carefully crafted `func` can make one an error, but not so carefully made ones might not. It becomes a hard(er)-to-use-correctly issue.
 The type system would prevent it.
Only if it is assisted by the programmer. If the type system could distinguish all the cases, i.e. there is no case where `f""` and `i""` work both, you wouldn't need the distinction in the first place. One could do a best effort approach, but I agree that weak typing is bad.
Dec 13 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 13 December 2021 at 15:42:43 UTC, Q. Schroll wrote:
 If I understand your suggestion correctly, both would compile, 
 but be handled differently. It's a one-keystroke difference and 
 people will conflate `i""` and `f""` for sure and it could lead 
 to serious vulnerabilities. Carefully crafted `func` can make 
 one an error, but not so carefully made ones might not. It 
 becomes a hard(er)-to-use-correctly issue.
I don't think api's should take the interpolated-list at all. That would be a sign of a weakly typed api. I would prefer something like ```sql"…"```, ```css"…"``` etc.
 the first place. One could do a best effort approach, but I 
 agree that weak typing is bad.
It is bad, yes. C is borderline untyped in some cases.
Dec 13 2021
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Monday, 13 December 2021 at 16:40:31 UTC, Ola Fosheim Grøstad 
wrote:
 I would prefer something like ```sql"…"```, ```css"…"``` etc.
How would you implement those?
Dec 13 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 13 December 2021 at 16:59:47 UTC, Adam D Ruppe wrote:
 On Monday, 13 December 2021 at 16:40:31 UTC, Ola Fosheim 
 Grøstad wrote:
 I would prefer something like ```sql"…"```, ```css"…"``` etc.
How would you implement those?
That really depends on what your philosophy is. I've given some hints above. What do you want to achieve? 1. better IDE support? 2. total control in metaprogramming for each application? 3. types that are shared between libraries (E.g. multiple frameworks using the same sql-literal) 4. solid error messages from the compiler without libraries having to go out of their way to provide it? If you want 1, 3, 4 then you probably should consider using a validating grammar in the compiler. If you want 2, then you can make it a type like I suggested above.
Dec 13 2021
parent reply Adam Ruppe <destructionator gmail.com> writes:
On Monday, 13 December 2021 at 23:35:40 UTC, Ola Fosheim Grøstad 
wrote:
 If you want 1, 3, 4 then you probably should consider using a 
 validating grammar in the compiler. If you want 2, then you can 
 make it a type like I suggested above.
The DIP covers all this and has an actual answer.
Dec 13 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 December 2021 at 00:04:40 UTC, Adam Ruppe wrote:
 The DIP covers all this and has an actual answer.
No, the DIP is a hack. I've pointed to other answers and you are smart enough to figure it out, but you have no interest in making D more than a language for enthusiasts. For D to be an alternative to C++ it has to clean up and provide stronger typing.
Dec 14 2021
parent reply Bruce Carneal <bcarneal gmail.com> writes:
On Tuesday, 14 December 2021 at 08:04:30 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 14 December 2021 at 00:04:40 UTC, Adam Ruppe wrote:
 The DIP covers all this and has an actual answer.
No, the DIP is a hack.
Summarizing earlier comments, I disagree.
 I've pointed to other answers and you are smart enough to 
 figure it out, but you have no interest in making D more than a 
 language for enthusiasts.
This is a curious comment. Antonyms for "enthusiast" include: adversary, critic, detractor, ... Given Adam's considerable assistance to beginners in Discord and elsewhere, perhaps more than anyone else in the forums, I find this a wildly inaccurate comment as well.
 For D to be an alternative to C++ it has to clean up and 
 provide stronger typing.
Factually, no. D is already an alternative to C++ for some of us. Could it be a stronger alternative to C++? Sure, but it is and can be much more than that.
Dec 14 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 14 December 2021 at 14:24:44 UTC, Bruce Carneal wrote:
 Given Adam's considerable assistance to beginners in Discord 
 and elsewhere, perhaps more than anyone else in the forums, I 
 find this a wildly inaccurate comment as well.
He was dismissive when I pointed out that this DIP not be ideal for newbies, he took a pro-enthusiast stance. That's ok, but that is a pattern in the evolution of D that makes the language less accessible. It is driven by the most enthusiastic crowd.
 Factually, no.  D is already an alternative to C++ for some of 
 us.  Could it be a stronger alternative to C++?  Sure, but it 
 is and can be much more than that.
It is an alternative if you don't need frameworks, but in order to get enough people working with, to get a solid eco-system, you have to reach outside the enthusiast fold. There is nothing wrong with a language for enthusiasts, by enthusiasts, but it is a fairly narrow segment. D as a whole is gradually narrowing down into that enthusiasts' fold.
Dec 14 2021
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Tuesday, 14 December 2021 at 14:49:42 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 14 December 2021 at 14:24:44 UTC, Bruce Carneal 
 wrote:
 Given Adam's considerable assistance to beginners in Discord 
 and elsewhere, perhaps more than anyone else in the forums, I 
 find this a wildly inaccurate comment as well.
He was dismissive when I pointed out that this DIP not be ideal for newbies,
DIP's are not supposed to be for newbies. They are destined at the language implementers and advanced users to detect issues and solutions to the problems. They are not tutorials and should not cater to beginners.
 he took a pro-enthusiast stance. That's ok, but that is a 
 pattern in the evolution of D that makes the language less 
 accessible. It is driven by the most enthusiastic crowd.
Strange argument. It is like a car manufacturer would scold their engineers that their development plans cannot be read by an apprentice mechanic.
Dec 17 2021
parent reply bauss <jj_1337 live.dk> writes:
On Friday, 17 December 2021 at 09:42:30 UTC, Patrick Schluter 
wrote:
 DIP's are not supposed to be for newbies. They are destined at 
 the language implementers and advanced users to detect issues 
 and solutions to the problems. They are not tutorials and 
 should not cater to beginners.
I don't think he's referring to the DIP process, but rather what the DIP covered. Meaning the language construct and implementation.
Dec 17 2021
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Friday, 17 December 2021 at 10:14:32 UTC, bauss wrote:
 On Friday, 17 December 2021 at 09:42:30 UTC, Patrick Schluter 
 wrote:
 DIP's are not supposed to be for newbies. They are destined at 
 the language implementers and advanced users to detect issues 
 and solutions to the problems. They are not tutorials and 
 should not cater to beginners.
I don't think he's referring to the DIP process, but rather what the DIP covered. Meaning the language construct and implementation.
This is a documentation issue. That the implementation of the DIP might not be easily understood by newbies is imho irrelevant. The skill of the users might be a factor for the usage of the feature, not how it is put in the language. Look, Walter's initial proposition was much simpler and quite easier to understand. This proposition requires much higher skills to understand how it works (one needs to know what parameter tuples, templates, overloads etc.), yet Walter's proposition was a stinker (sorry for the language) because it opened the floodgate of substitution bugs, type mismatches and injection risks. Traps a newbie could easily fall into. On the new proposition, newbies might be stumped on certain behaviours (i.e. it's magic) but the language does the "right thing". If the "right thing" is a little bit more complicated, so be it.
Dec 17 2021
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 17 December 2021 at 11:32:19 UTC, Patrick Schluter 
wrote:
 This is a documentation issue. That the implementation of the
No, it is a usability issue.
Dec 17 2021
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 12/17/2021 3:32 AM, Patrick Schluter wrote:
 Look, Walter's initial proposition was much simpler and quite easier to 
 understand. This proposition requires much higher skills to understand how it 
 works (one needs to know what parameter tuples, templates, overloads etc.),
yet 
 Walter's proposition was a stinker (sorry for the language) because it opened 
 the floodgate of substitution bugs, type mismatches and injection risks. Traps
a 
 newbie could easily fall into.
I don't agree with that characterization at all.
Dec 17 2021
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Thursday, 9 December 2021 at 16:02:19 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 15:55:42 UTC, Ola Fosheim 
 Grøstad wrote:
 You can fix this with implicit conversion to string, but it 
 makes for weaker typing:
This has been discussed over many years. If you haven't read the previous DIPs and those too, you aren't contributing anything. It is a complete waste of time to go over this over and over and over and over and over and over again.
Ola may be ignorant of the previous DIP, I do not know. I certainly am. However, I have migration multi million LOC codebase toward safer string interpolations constructs that catched real bugs and hardened security. The kind of solution used then resemble much more what Ola describes than what the current proposal describes. The proposed solution has serious drawbacks compared to more standard approaches, to begin with, such as not behaving like an expression and requiring the consumer to be aware of the construct.
Dec 09 2021
parent Bruce Carneal <bcarneal gmail.com> writes:
On Thursday, 9 December 2021 at 16:34:23 UTC, deadalnix wrote:
 On Thursday, 9 December 2021 at 16:02:19 UTC, Adam D Ruppe 
 wrote:
 On Thursday, 9 December 2021 at 15:55:42 UTC, Ola Fosheim 
 Grøstad wrote:
 You can fix this with implicit conversion to string, but it 
 makes for weaker typing:
This has been discussed over many years. If you haven't read the previous DIPs and those too, you aren't contributing anything. It is a complete waste of time to go over this over and over and over and over and over and over again.
Ola may be ignorant of the previous DIP, I do not know. I certainly am.
I'm not an "expert" in this area but I have been following the DIPs and current discussion. FWIW I like the current DIP a lot. It may not be as terse as more specialized forms but, IIUC, it preserves all the relevant information in simple to process form. Seems like a very good intermediate representation.
Dec 09 2021
prev sibling parent WebFreak001 <d.forum webfreak.org> writes:
On Thursday, 9 December 2021 at 15:16:40 UTC, WebFreak001 wrote:
 [...]

 and if you want to actually access the tuple for variadic 
 template arguments (including the header) you could still do 
 this:

 ```d
 AliasSeq"hello $name"
 ```

 (or `alias I = AliasSeq;` and `I"hello $name"`)
this should have been: ```d tuple"hello $name" // or alias I = tuple; I"hello $name" ```
Dec 09 2021
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Thursday, 9 December 2021 at 14:25:58 UTC, WebFreak001 wrote:
 But don't you think it would be better if you could write:

 ```
 sql"SELECT x,y,z FROM {something} FROM {condition}"
 ```

 [...]
Love the idea of having type-safety with this! JS has similar syntax with `` sql`...` `` where it will call the function `sql` with the parts of the interpolated string. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
This approach has proven extremely useful in many contexts. I'm not sure why this is frowned upon.
Dec 09 2021
parent Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 9 December 2021 at 16:24:12 UTC, deadalnix wrote:
 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
This approach has proven extremely useful in many contexts. I'm not sure why this is frowned upon.
This approach is virtually identical to the dip in substance. The only difference is in syntax. In Javascript, it is a magic function call syntax. The D proposal is to use standard function call syntax, which fits D better since we have two kinds of "function calls" - template arguments and run-time arguments. Reusing existing syntax lets us use this in both cases without any special rules. But both pass similar data and have similar results. The Javascript approach is good evidence that this separation of data and strings is desirable and useful.
Dec 09 2021
prev sibling parent deadalnix <deadalnix gmail.com> writes:
On Thursday, 9 December 2021 at 12:43:31 UTC, Adam D Ruppe wrote:
 On Thursday, 9 December 2021 at 10:43:07 UTC, deadalnix wrote:
 So I read the proposal for string interpolation in D, which I 
 understand to be this one: 
 https://github.com/John-Colvin/YAIDIP

 The immediate thing that stroke me is the shell example. The 
 proposed exemple is simply terrible code as it allows for 
 shell injection.
You say you read it, then say something that is blatantly false about it. This dip does NOT produce strings. It produces argument lists. The receiving function knows what was part of the string literal and what were arguments and can process them accordingly.
I see. I misunderstood that part, so scratch that. It's not as bad as I thought, but it definitively feel hacky. It is unclear to me this is worth the complexity.
Dec 09 2021
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/9/21 5:43 AM, deadalnix wrote:
 So I read the proposal for string interpolation in D, which I understand 
 to be this one: https://github.com/John-Colvin/YAIDIP
 
 The immediate thing that stroke me is the shell example. The proposed 
 exemple is simply terrible code as it allows for shell injection.
It depends on the executeShell function that accepts interpolations. It could just text-ify the thing (convert to a string) or properly escape anything in the interpolation portions. Granted, the DIP does not discuss this possibility.
 
 One of the motivating example is SQL prepared statements, but once 
 again, replacing this by the proposed string interpolation means SQL 
 injection.
No, it doesn't. This tells me you are missing something in your understanding of the proposal. -Steve
Dec 09 2021
next sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 9 December 2021 at 14:18:35 UTC, Steven 
Schveighoffer wrote:
 Granted, the DIP does not discuss this possibility.
For this specific example, the text says the elements are preprocessed with escapeShellCommand, which would be necessary for format() and text(), but not necessarily for the interpolated tuple. It is more of a syntax comparison than a feature demo. I do think the dip is legitimately weak on actually showing this aspect, even if the facilities are there in the substance.
Dec 09 2021
prev sibling parent deadalnix <deadalnix gmail.com> writes:
On Thursday, 9 December 2021 at 14:18:35 UTC, Steven 
Schveighoffer wrote:
 No, it doesn't. This tells me you are missing something in your 
 understanding of the proposal.

 -Steve
You are correct, apologies.
Dec 09 2021
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 12/9/2021 2:43 AM, deadalnix wrote:
 So I read the proposal for string interpolation in D, which I understand to be 
 this one: https://github.com/John-Colvin/YAIDIP
This is the one I proposed: https://github.com/dlang/DIPs/blob/master/DIPs/rejected/DIP1027.md which is simple and straightforward.
Dec 10 2021
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 wrote:
 Usage example: 
 https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler

 What do you think of these extended interpolated string 
 expressions? I think these would fit well into D, and could 
 give some new motivation now that we have had our interpolated 
 strings DIPs rejected once and withdrawn once.
Not sure if this is much better than FormattableString overloads: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#implicit-conversions-and-how-to-specify-iformatprovider-implementation
Dec 09 2021
parent Rumbu <rumbu rumbu.ro> writes:
On Thursday, 9 December 2021 at 12:21:06 UTC, Kagamin wrote:
 On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 
 wrote:
 Usage example: 
 https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler

 What do you think of these extended interpolated string 
 expressions? I think these would fit well into D, and could 
 give some new motivation now that we have had our interpolated 
 strings DIPs rejected once and withdrawn once.
Not sure if this is much better than FormattableString overloads: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#implicit-conversions-and-how-to-specify-iformatprovider-implementation
The interpolated handler can skip some expressions in the interpolated string or can use more performant inner details like spans. FormattableString parses *all* arguments and format them.
Dec 10 2021
prev sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 8 December 2021 at 10:46:31 UTC, WebFreak001 wrote:
 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings


 compiler checks if the interpolated string is assigned to a 
 type that satisfies the interpolated string handler pattern
Usage example: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler What do you think of these extended interpolated string expressions? I think these would fit well into D, and could give some new motivation now that we have had our interpolated strings DIPs rejected once and withdrawn once.
It's fun how we discuss how we should do this while other have solved this years ago. Just do what others do, then at a later stage we can "improve" it. D will probably never get string interpolation tbh, we will just discuss various solutions, but no one will be chosen.
Dec 17 2021
parent reply bachmeier <no spam.net> writes:
On Friday, 17 December 2021 at 12:14:16 UTC, Imperatorn wrote:

 It's fun how we discuss how we should do this while other have 
 solved this years ago.

 Just do what others do, then at a later stage we can "improve" 
 it.

 D will probably never get string interpolation tbh, we will 
 just discuss various solutions, but no one will be chosen.
Don't be ridiculous. When D gets string interpolation in 2078, it'll be better than any of the 2021 implementations in other languages.
Dec 17 2021
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Friday, 17 December 2021 at 14:37:05 UTC, bachmeier wrote:
 On Friday, 17 December 2021 at 12:14:16 UTC, Imperatorn wrote:

 It's fun how we discuss how we should do this while other have 
 solved this years ago.

 Just do what others do, then at a later stage we can "improve" 
 it.

 D will probably never get string interpolation tbh, we will 
 just discuss various solutions, but no one will be chosen.
Don't be ridiculous. When D gets string interpolation in 2078, it'll be better than any of the 2021 implementations in other languages.
Omg yes, it will be awesome. You will just think about what you want to do and it will be created 🌅
Dec 18 2021
parent reply bauss <jj_1337 live.dk> writes:
On Saturday, 18 December 2021 at 08:50:16 UTC, Imperatorn wrote:
 On Friday, 17 December 2021 at 14:37:05 UTC, bachmeier wrote:
 On Friday, 17 December 2021 at 12:14:16 UTC, Imperatorn wrote:

 It's fun how we discuss how we should do this while other 
 have solved this years ago.

 Just do what others do, then at a later stage we can 
 "improve" it.

 D will probably never get string interpolation tbh, we will 
 just discuss various solutions, but no one will be chosen.
Don't be ridiculous. When D gets string interpolation in 2078, it'll be better than any of the 2021 implementations in other languages.
Omg yes, it will be awesome. You will just think about what you want to do and it will be created 🌅
Just don't forget to mark your functions with usestrings useinterpolatedstrings thisiseventmoresafethan safe nogcbutonlyalittlebit
Dec 18 2021
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 18 December 2021 at 19:44:54 UTC, bauss wrote:
 On Saturday, 18 December 2021 at 08:50:16 UTC, Imperatorn wrote:
 On Friday, 17 December 2021 at 14:37:05 UTC, bachmeier wrote:
 On Friday, 17 December 2021 at 12:14:16 UTC, Imperatorn wrote:

 [...]
Don't be ridiculous. When D gets string interpolation in 2078, it'll be better than any of the 2021 implementations in other languages.
Omg yes, it will be awesome. You will just think about what you want to do and it will be created 🌅
Just don't forget to mark your functions with usestrings useinterpolatedstrings thisiseventmoresafethan safe nogcbutonlyalittlebit
🎂🎉😎
Dec 18 2021