Tuples, CTFE, and Sliding Template Arguments

Nickolay Bukreyev buknik95 at ya.ru
Sat Jan 13 18:43:46 UTC 2024


On Saturday, 13 January 2024 at 06:46:54 UTC, Walter Bright wrote:
> So you agree it is not simpler :-)

Let’s compare them side by side.

```d
// DIP1027 + Sliding Template Arguments

// core.interpolation:

enum FormatString: string;
// Or, alternatively:
// struct FormatString { string s; }

// User-library code:

string generateSql(FormatString fmt) {
     import std.conv: text;

     string sql;
     int number;
     for (size_t i = 0; i < fmt.length; ++i) {
         char c = fmt[i];
         if (c == '%' && i + 1 < fmt.length && fmt[i + 1] == 's') {
             sql ~= text('?', ++number);
             ++i;
         } else if (c == '%' && i + 1 < fmt.length && fmt[i + 1] 
== '%')
             ++i;
         else
             sql ~= c;
     }
     return sql;
}

auto execi(FormatString fmt, Args...)(Sqlite db, Args args) {
     enum query = generateSql(fmt); // CTFE.
     auto statement = Statement(db, query);
     static foreach (i, arg; args)
         statement.bind(i + 1, arg);
     return statement.execute();
}

// User code:

db.execi(i"SELECT * FROM items WHERE id = $desiredId");
// Desugars to:
db.execi(cast(FormatString)"SELECT * FROM items WHERE id = %s", 
desiredId);
```

Vs.

```d
// Steven's proposal + Sliding Template Arguments

// core.interpolation:

struct Interpolation {
     immutable(string)[ ] parts;
}

// User-library code:

string generateSql(Interpolation interp) {
     import std.conv: text;

     string sql;
     foreach (i, part; interp.parts)
         sql ~= i & 0x1 ? text('?', i / 2 + 1) : part;
     return sql;
}

// No changes here.
auto execi(Interpolation interp, Args...)(Sqlite db, Args args) {
     enum query = generateSql(interp); // CTFE.
     auto statement = Statement(db, query);
     static foreach (i, arg; args)
         statement.bind(i + 1, arg);
     return statement.execute();
}

// User code:

db.execi(i"SELECT * FROM items WHERE id = $desiredId");
// Desugars to:
db.execi(Interpolation(["SELECT * FROM items WHERE id = ", 
"desiredId", ""]), desiredId);
```

Which one is simpler?

(Note that neither of them will actually work due to the fact 
`FormatString`/`Interpolation` is not the first argument, but 
that’s not the point I’m arguing here.)


More information about the Digitalmars-d mailing list