1
$\begingroup$

In Rust:

#[derive(Display)]
struct Foo<T>(T);

If T conforms to the Display trait, then Foo<T> can automatically implement Display using a macro.

Is there an approach to accomplish this automatic implementation that doesn't rely on the macro system?

$\endgroup$
3
  • 1
    $\begingroup$ In C# attributes and reflection can be used to automatically implement behavior: [DebuggerDisplay("x = {x} y = {y}")] class Foo. It's not an interface though. DebuggerDisplay $\endgroup$ Commented Dec 1, 2023 at 9:20
  • 1
    $\begingroup$ Either reflection (basically, resolve the structure and implementation at runtime instead of compile time), or structural type-level hackery like Haskell's GHC generics (wiki.haskell.org/GHC.Generics) $\endgroup$
    – tarzh
    Commented Dec 1, 2023 at 13:02
  • 1
    $\begingroup$ Or compile-time execution (comptime) like in Zig (kristoff.it/blog/what-is-zig-comptime) $\endgroup$
    – tarzh
    Commented Dec 1, 2023 at 15:51

1 Answer 1

4
$\begingroup$

Compile time source generation

That is, instead of using simple string concatenation (via a crude macro system) or trying to make the macro system Turing complete with a lot of extra syntax, you could use the very source language to do this.

Something like C# source generators.

This is a extreme form of the lexer hack, where the compiler runs some previous compiled source generator at some specifics steps on parsing and/or compiling stages of normal code, so this source generators inject pure new code, or directly inspect and create/modify AST nodes in the intermediary compiled state.

#[sgen(Display)]   // Register a source generator for later execution.
struct Foo<T>(T);  // The "visible" source code, parsed from file.

// When the compiler finds the end of struct in visible source code,
// execute registered source generators, to inject new code or to
// modify the parsed AST. (after the only `;` in this example)

If the compiler is already bootstrapped, it's easier to implement source generators, as any internal compiler infrastructure can be exposed without code duplication.

$\endgroup$
1
  • 1
    $\begingroup$ Another example is Swift's Sourcery and Kotlin's KSP. $\endgroup$
    – tarzh
    Commented Dec 1, 2023 at 21:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .