Yet another terrible compile time argument proposal

Steven Schveighoffer schveiguy at gmail.com
Sun Jan 14 21:27:44 UTC 2024


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


More information about the Digitalmars-d mailing list