Rust’s type system is pretty powerful, but I had an idea. First, let’s start simple:
Macro-like fns
(can these really be called fns?)
Macro-like fns are strongly-typed, highly hygienic code generators. They’re in many ways less powerful than macros, but that’s also what makes them more powerful.
All code inside the fn becomes part of the caller. Statics create real statics (and can thus be generic) as part of the caller but only accessible inside the mlfn invokation. Different invokations create different statics.
Example:
macro fn post_event<T: Event + ?Sized>(bus: &EventBus, event: &mut T) -> bool {
// see eventbus post_event! for what goes in here
}
Due to their ability to insert statics into the caller’s compilation unit, they have a few restrictions:
- The caller cannot pass a generic
<T>
downstream, unless it’s also a mlfn. - mlfn can’t be converted into fn references or Fn*.
These make them a poor choice for some stuff, but they’d be great for me.
They can also be associated with an object, so rather than taking the bus by &EventBus it could take &self.
As they can be part of a type, the evaluation/expansion can also depend on the results of a type-system computation. So we go into the next step:
CTR
Compile-time reflection is the ability to expand something like SuperTraits<dyn Foo>::Output
into something like a variadic generic containing (dyn Bar, dyn Baz)
. I call this a TypeFn. Combined with mlfn, eventbus would be able to automatically post to all supertraits, without you manually specifying each one of them.
The type system is already recursive, and this doesn’t make it any less recursive, so we don’t need to worry about that
Finally, I still need specialization to make eventbus the best. But that one is already being worked on.