Interesting usage of recursive mixins and interpolation sequence parametrization for repeating code
WB
witold.baryluk at gmail.com
Mon Sep 29 20:57:48 UTC 2025
I just discovered quite an interesting technique for writing code
that needs to be repeated / interleaved / vectorized.
It uses a clever recursive mixin, where first mixin generating
function receives a string, that is to be used as interpolation
sequence inside that function, and then interpolates it (and
constructs that interpolation sequence string using interpolation
string - that part is optional tho).
It is handy.
```d
@attribute("flatten")
KV*[4] GetWithHash4(const ref K k0, H hash0, const ref K k1, H
hash1, const ref K k2, H hash2, const ref K k3, H hash3) {
static enum N = 4;
KV*[4] ret;
static string repeat_i(string pattern)() {
string ret;
import std.conv : to, text;
foreach (i_; 0 .. N) {
const string i = i_.to!string;
ret ~= mixin(i"i\"$(pattern)\"".text).text;
// ret ~= mixin(i"i\"$(pattern)\".text".text); // also
works.
}
return ret;
}
mixin(repeat_i!"bool r$(i)_search = true;");
ulong todo_count = N;
mixin(repeat_i!"auto slot_idx$(i) = hash$(i) %
slots.length;");
while (todo_count != 0) {
mixin(repeat_i!"Slot* slot$(i) = &slots[slot_idx$(i)];");
asm { "" ::: "memory"; };
mixin(repeat_i!"auto slot$(i)_hash = slot$(i).hash_;");
asm { "" ::: "memory"; };
mixin(repeat_i!q{
if (r$(i)_search) {
if (slot$(i)_hash == hash$(i)) {
if (slot$(i).kv.k == k$(i)) {
ret[$(i)] = &slot$(i).kv;
r$(i)_search = false;
todo_count--;
}
} else if (slot$(i)_hash == EMPTY) {
r$(i)_search = false;
todo_count--;
} else {
slot_idx$(i) = (slot_idx$(i) + 1) % slots.length;
}
}
});
}
return ret;
}
```
The interleaving technique here, I call software threading
(similar to hyper-threading / SMT on CPUs, running multiple
context in parallel). I used it in the past using C macros, maybe
10 years ago, for similar effect. But in D, it actually is nicer
to achieve.
Purposes of the code above are not that important, but I thought
it might be interesting sharing the double mixin with double
interpolation technique for building code, without a need for
extra functions. And quite compact and readable code.
The iteration over integers / string here is trivial to extend to
other options, like arrays, for other code generation purposes.
More information about the Digitalmars-d
mailing list