We are forking D

Timon Gehr timon.gehr at gmx.ch
Mon Jan 8 20:32:26 UTC 2024


On 1/8/24 03:10, Walter Bright wrote:
> On 1/7/2024 3:45 PM, Timon Gehr wrote:
>> Only if you pass the i-string as a template parameter (which might not 
>> even work because any non-symbol expression will need to be evaluated 
>> at compile time but maybe cannot).
> 
> Currently D internally supports non-trivial expressions as tuples. 
> DIP1027 relies on that, as:
> 
> ```
> int i = 4;
> writefln(i"hello $(3 + i)");
> ```
> 
> prints:
> 
> hello 7
> ...

Well yes, but my point was you can't pass that to a template. You were 
the one passing the istring to a template as part of a suggested routine 
operation, it was not me.

> But, if the tuple is created with:
> 
> ```
> template tuple(A ...) { alias tuple = A; }
> ```
> 
> then a non-trivial expression cannot be passed to it, as it will not 
> work as an alias parameter.

Yes.

> This is a general shortcoming in D, not a specific problem with DIP1027.
> ...
The specific problem with DIP1027 is that it has problems for which your 
suggested solution is to pass an istring to a template, which does not 
work. DIP1036e simply does not have such problems, because it separates 
compile-time from runtime information in a way where information is not 
lost when passing the istring to a function template.

> We've been moving towards:
> 
> ```
> auto tup = (1, 3 + i);
> ```
> for a while now, which is why comma expressions have been deprecated.
> ...

Which is good, but I fear your intention is to use this syntax to create 
auto-expanding entities, which would be bad.

In any case, this still does not allow `(1, 3 + i)` to be passed as a 
template parameter.

> Amusingly, istrings can be used to create non-trivial expression tuples 
> with this:
> 
> ```
> int i = 4;
> auto tup2 = i"$i $(3 + i)"[1..3];
> writeln("a tuple: ", tup2);
> ```
> 
> which prints:
> 
> a tuple: 47
> ...

`tup2` is a sequence of aliases to local variables. It is exactly the 
same as what we get from this:

```d
import std.typecons:tuple;
auto tup2 = tuple(i,3+i).expand;
```

I get that what you mean is that in the right-hand side you have an 
actual sequence of expressions. It used to be the case that UDAs did not 
evaluate such expressions but this has been fixed in the meantime.

> I can't recommend doing things that way, but it just illustrates 
> istrings as being a building block rather than an end product.
> ...

And yet with DIP1027 they are presented to a function that would consume 
them just like the final product without any way of distinguishing a 
building block from an end product.

> As for detecting string literals, I have tried a few schemes to no 
> avail. It may have to be added with a __traits, which is where we put 
> such things.
> ...

You cannot detect whether a function argument was a string literal in 
the current language even if you add a `__traits`, because such details 
are not passed through implicit function template instantiation.

And anyway, what do you do if a user decides to do something like this?

i"$("hi") $("%s") $("hi") $(i"$("hi")")"

DIP1036e can handle this relatively naturally.

> Trying that with DIP1036 means there are several more entries added to 
> the tuple, which would have to be filtered out.
> ...

Building block vs end product applies here.

> 
>> Also, what do you do if someone nests multiple i-strings? DIP1036 
>> handles it. etc. The design is simple but it addresses many issues 
>> that authors of competing proposals did not even think about.
> 
> Nested istrings would do the expected - create a tuple within a tuple, 
> which gets flattened out. You'd likely wind up with a compile time error 
> that there are too many arguments for the format. Recall that the 
> istring is simply converted to a tuple, after that, predictable tuple 
> rules are followed.
> ...

I want it to work instead of fail to work or pretend to work in a way 
that is predictable to a type checker developer like you or me. ;)

> However, the nested istring can always be inserted as an argument to the 
> `text` function which will expand it into a single argument, and no 
> tuple twubble.
> ...

At which point you may get back the security vulnerabilities.

> In general, you and I agree that D should move towards much better tuple 
> support.

Yes.

NB: I think among others that entails having a clean separation between 
auto-expanding sequences and "real" tuples that do not auto-expand.

Note that the fact that expression sequences auto-expand into any 
context does not help either DIP1027 nor DIP1036e (on the contrary). The 
reason why DIP1036e uses an expression sequence is that structs have 
some limitations.

> DIP1027 fits right in with that, as it does no magic. Better 
> tuple support will fit right in in extending istring power, rather than 
> making istring itself more powerful.

I think the things DIP1036e allows to do that DIP1029 does not still do 
not work with DIP1027 together better tuple support. Rather you would 
need to add more introspection features to implicit template 
instantiation to even approach what DIP1036e does.


More information about the Digitalmars-d mailing list