Yet another terrible compile time argument proposal

Timon Gehr timon.gehr at gmx.ch
Sun Jan 14 22:15:56 UTC 2024


On 1/14/24 22:27, Steven Schveighoffer wrote:
> On Friday, 12 January 2024 at 22:35:54 UTC, Walter Bright 
> [wrote](https://forum.dlang.org/post/unseru$167e$1@digitalmars.com):
>> Given the interest in CTFE of istrings, I have been thinking about 
>> making a general use case out of it instead of one specific to istrings.
> 
> Been also thinking about this and I have the following conclusions:
> 
> - Walter's proposal seems super hacky and probably shouldn't be done. I 
> don't like the idea of magically migrating an argument from one place to 
> match a parameter in another, especially based on arbitrary rules that 
> are constructed to fit the current use case (and in fact was shown not 
> to actually help in the long run.
> - I really *really* like the idea of passing a simple struct at either 
> runtime or compile time to a function over instrumented parameters (like 
> the `InterpolationLiteral!"str"` or Rikki's attribute passing (which 
> basically becomes extra hidden template parameters, that the function 
> might not even use).
> - The syntax for any such mechanism should be obvious and straightforward.
> 
> Instead of pushing runtime value arguments into compile time value 
> parameters, why not just identify that they are compile time in the 
> argument list? I like the [idea from Mathis Beer 
> (FeepingCreature)](https://forum.dlang.org/post/wkwgipddfegevbrimiav@forum.dlang.org) that was linked by Nick earlier, but that also has some (I think) ambiguous syntax, and requires some coordination between separate parts.
> 
> I'm going to propose something that furthers the baggage of `enum`, but 
> that is the tool we currently have... Happy to think about better 
> syntax. But why not just:
> 
> ```d
> void foo(T)(T x, enum string s)
> {
>     pragma(msg, s); // s is compile-time
> }
> 
> void main(string[] args)
> {
>     foo(1, "hi"); // ok
>     foo(1, "hello"); // ok, but a different instantiation
>     foo(1, args[1]); // error, second argument must be compile time
> }
> ```
> 
> Basically, an enum attributed parameter in the runtime parameter list 
> requires a compile-time value, and implicitly adds it to the template 
> arguments for the template instantiation. This is very similar to 
> FeepingCreature's proposal, but without the extra ambiguity. There is no 
> mechanism to explicitly pass the parameter in the compile-time arugment 
> list.
> 
> Details can be worked out. But first wanted to see if it makes 
> preliminary sense to everyone? I'm looking specifically at language 
> experts, what am I missing?
> 
> In reference to the SI proposals (and keep in mind, this is still 
> *orthogonal* to the format string vs. interpolation segments, which I'm 
> still firmly on the side of passing the parsed data to the user), it 
> could look something like this:
> 
> ```d
> struct Interpolation
> {
>     immutable string[] parts;
> }
> 
> auto execi(Args...)(Database db, enum Interpolation interp, Args args)
> {
>     enum sqlStr = generateSQLString(interp);
>     return exec(db, sqlStr, args);
> }
> ```
> 
> The beauty of this is, the string interpolation proposal becomes a 
> *direct translation* from the string literal to a sequence of simple 
> values (similar to DIP1027).
> 
> I know [one point from 
> Jonathan/Nickolay](https://forum.dlang.org/post/lplyefclptgxonbzyzzy@forum.dlang.org) has already been brought up against this idea:
> 
> On Sunday, 14 January 2024 at 07:54:23 UTC, Nickolay Bukreyev wrote:
>> On Sunday, 14 January 2024 at 02:49:24 UTC, Jonathan M Davis wrote:
>>> And I'd really rather not have runtime arguments silently become 
>>> compile-time arguments base on how a function signature is written 
>>> (which could change when the code is refactored).
>>
>> Agreed.
>>
>> [story about removing unnecessary template instantiations by searching 
>> for !]
>>
> 
> I see this point. I don't know how to reconcile my desire to have an 
> expression that has compile-time data passed through it, while having it 
> be an expression that works wherever expressions are expected, without 
> having to separate the two into the compile time and runtime pieces. 
> It's just so ugly, and things really should be where they belong 
> cognitively.
> 
> I'm open to alternatives. Or preliminary limitations. But that is the 
> gist of it -- I want compile-time information passed via a string 
> interpolation tuple, like it is for DIP1036e.
> 
> -Steve

See also this: https://forum.dlang.org/post/unsgir$1a5m$1@digitalmars.com

I think there is a way that is somewhat nicer than both of those ideas.

1. Allow `:` syntax for runtime parameters (this already works for 
template parameters):

```d
void foo(int x:1, int y){ } // 1
void foo(int x:2, int y){ } // 2

void main(){
     foo(1,2); // calls 1
     foo(2,3); // calls 2
}
```

2. Make it match during IFTI.


```d
void foo(int x)(int:x, int y){ }

void main(){
     foo(1,2); // calls foo!1(2)
     foo(2,3); // calls foo!2(3)
}
```

In this example, I have omitted the runtime parameter name, this is 
already a D feature.


3. Allow `enum` (and maybe `alias`) storage class on such parameters to 
omit them at runtime.

```d
void foo(int x)(enum int:x, int y){ }

void main(){
     foo(1,2); // calls foo!1(2)
     foo(2,3); // calls foo!2(3)
}
```

Maybe it is best to restrict `:` syntax to `enum` parameters but then at 
least the template parameter list is not being modified by the feature.


More information about the Digitalmars-d mailing list