Is it possible to write a variadic function using macro_rule?

pub fn new0<T: Send + 'static>(func: fn() -> T) -> JoinHandle<T> {
    let x = move || {
        return func();
    return std::thread::spawn(x);

pub fn new1<T: Send + 'static, T0: Send + 'static>(func: fn(T0) -> T, t0: T0) -> JoinHandle<T> {
    let x = move || {
        return func(t0);
    return std::thread::spawn(x);

macro_rule! new {
	(`aaa`) => {
		let x = move || {
			return `bbb`;
		return std::thread::spawn(x);

Rust macro is powerful, but has very complicated syntax to use.
I want to write a new() macro to receive variadic arguments.
Now, I don't know if it is possible, and if so, how to modify aaa and bbb?

First, to clear up what looks like some confusion, it's the macro itself that is variadic.

Writing macros is difficult because it's its own DSL that is distinct from the rest of the language. You might have some success in understanding this DSL by reading some of the documentation:

  1. Macros - The Rust Programming Language (
  2. macro_rules! - Rust By Example (
  3. Introduction - The Little Book of Rust Macros (
  4. Macros - The Rust Reference (

As for implementing your macro, there are a few things to keep in mind. Like the fact that the declarative macro DSL operates on "token trees", not on things that are usually considered atomic units of code. Accepting a closure, for instance, requires building up the token tree that will be matched when the macro is used. And passing a function name instead of a closure requires its own match arm (because the function name is a single identifier, and identifiers are a specific kind of token).

I don't know if any of that will make any sense until you've read a bit about declarative macros. But here's what I came up with for implementing it, based on your example code: Rust Playground

There are probably better ways to do this. And FWIW the currying looks very silly with closures. You can normally just let the closure capture its environment instead of passing arguments.


@parasyte is entirely correct about how macros work. Rust does not have variadic functions.

However, it seems to me like what you're doing (based on your example) could dodge needing a variadic API at all. I would instead write something like this:

pub fn new<T: Send + 'static, F: FnOnce() -> T>(func: F) -> JoinHandle<T> {

FnOnce is a trait for functions which can only be called once, including closures. A caller might do the equivalent:

// instead of using new0
let _ = new(func);
// instead of using new1
let _ = new(move || func(t0));

However, this is simply me trying to infer what you're actually doing from your example. If you're trying to achieve something different, let us know in more detail so we can help more!


the error message is not pretty, and there might be edge cases, but it should work for common cases.

macro_rules! new {
    ($entry:expr $(, $arg:expr)* $(,)?) => {
		std::thread::spawn(move || {

Your solution is very good. My intention is to use rust macro like a variadic function or overloaded function, that is, the same function name can accept different argument type or number.

Thank you. It is just I want.
A programming language contains basic syntax and syntax-based standard library.
So, I want to wrap the standard library more comfortable for me.

Your solution is functional and more simpler.
I will spend time to check the diff from yours and @parasyte 's one.

The difference is mainly the kinds of inputs that the macro will accept, and thus provides different error messages for different kinds of erroneous syntax. @nerditation's answer is the bare minimum required to produce the desired result.

What I wrote takes the first step toward providing a better user experience with invalid inputs. (But a whole lot more is needed for it to become even mostly usable in any nontrivial scenario.)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.