Just a small built in macro idea

The macro looks like this:

for_each! $metavar in $[%comma separated set of idents%] {
    //code template with $metavar
}

The core point is that it gains no hyhiene at all. The code from template is simply copy pasted for each ident inside of [].

It can make writing boiler plate cost one macro declaration less:
From this

fn does_boring_stuff(){
macro_rules! m(...) {...}
...
m!(id1);
m!(id2);
m!(id2);
...
}

to this:

fn still_does_boring_stuff() {
for_each! $id in $[id1,id2,id3,...] {
   //do boring stuff once
}
}

This seems like something that could be implemented as a function-like procedural macro in an external crate. (I'm pretty sure there's nothing about it that would need to be a compiler built-in).

2 Likes

No, as of macro, for example, can't introduce local variable (to the outer scope).

Also, writing a dedicated macro for generating anything like the code from example feels like overkill.

Macros can definitely introduce local variables. This macro is very close to the one you described:

macro_rules! for_each {
    ([dollar = $_:tt] $name:ident in [$($token:tt),* $(,)?] { $($body:tt)* }) => {
        macro_rules! __inner {
            ($_ $name:tt) => { $($body)* };
        }
        $(__inner!($token);)*
    };
    ($($tt:tt)*) => { for_each! { [dollar = $] $($tt)* } };
}

Usage like:

for_each!(id in [id1, id2, id3] {
    let $id = 5;
    println!("{}", $id);
});
4 Likes