What are the use cases for macros which define macros?


#1

Other than the actual definition of macro_rules itself (although if anyone can explain why macro_rules is defined in this way, that would be useful too).


#2

One could possibly create a macro that generates macros mimicking functions with default arguments.

I think it would be better to add default function arguments (and/or overloading) directly to the language however…


#3

Macros than can generate macros could finally fix my redis-rs command structure. Currently I have a disgusting hack in there which expands macros twice into two different structs.

The use would be to do something like this:

define_methods!(classbuilder,
   fn foo() {}
   fn bar() {}
)

classbuilder!(struct Foo)
classbuilder!(struct Bar)

As an example.


#4

Any time you have a library that needs to be used in a particular way that you can abstract over, and gets used repeatedly. More generally, if you’re writing a macro that abstracts over creating some defintitions, and you realize one of those definitions should be/is already a macro.

For example, the define-ffi-definer macro in Racket. In Rust, the extern block covers this, but you might want to write a bunch of wrapped versions of unsafe FFI calls. Then you write a macro to generate each one, since the pattern for wrapping is pretty similar. But in your next FFI binding, you write basically the same macro, and so on. Instead, there should be a library that abstracts that pattern, instead of copy/paste/modify from binding to binding.

There are lots of other uses cases, but this is a fairly representative one.


#5

@mitsuhiko I don’t think I understand your example, sorry. Are you giving just the uses of the macros here? Or is define_methods defining a a macro? What would the definition of define_methods look like?


#6

Look at implement_commands here: https://github.com/mitsuhiko/redis-rs/blob/master/src/redis/commands.rs

In an ideal world, instead of implement_commands making two impls it could just define another macro, and you could then use the macro in your own impl body. That way the code would become clearer and much more extensible.