Skip to content

Commit

Permalink
Separate naive and working callback snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
smheidrich authored and Veykril committed May 14, 2023
1 parent 4323e63 commit b31bb99
Showing 1 changed file with 20 additions and 19 deletions.
39 changes: 20 additions & 19 deletions src/decl-macros/patterns/callbacks.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
# Callbacks

```rust
macro_rules! call_with_larch {
($callback:ident) => { $callback!(larch) };
}

macro_rules! expand_to_larch {
() => { larch };
}
Due to the order that macros are expanded in, it is (as of Rust 1.2) impossible to pass information to a macro from the expansion of *another* macro:

```rust
macro_rules! recognize_tree {
(larch) => { println!("#1, the Larch.") };
(redwood) => { println!("#2, the Mighty Redwood.") };
Expand All @@ -18,27 +12,34 @@ macro_rules! recognize_tree {
($($other:tt)*) => { println!("I don't know; some kind of birch maybe?") };
}

macro_rules! expand_to_larch {
() => { larch };
}

fn main() {
recognize_tree!(expand_to_larch!());
call_with_larch!(recognize_tree);
// first expands to: recognize_tree! { expand_to_larch ! ( ) }
// and then: println! { "I don't know; some kind of birch maybe?" }
}
```

Due to the order that macros are expanded in, it is (as of Rust 1.2) impossible to pass information to a macro from the expansion of *another* macro.
This can make modularizing macros very difficult.

An alternative is to use recursion and pass a callback.
Here is a trace of the above example to demonstrate how this takes place:
An alternative is to use recursion and pass a callback:

```rust,ignore
recognize_tree! { expand_to_larch ! ( ) }
println! { "I don't know; some kind of birch maybe?" }
```rust
// ...

call_with_larch! { recognize_tree }
recognize_tree! { larch }
println! { "#1, the Larch." }
// ...
macro_rules! call_with_larch {
($callback:ident) => { $callback!(larch) };
}

fn main() {
call_with_larch!(recognize_tree);
// first expands to: call_with_larch! { recognize_tree }
// then: recognize_tree! { larch }
// and finally: println! { "#1, the Larch." }
}
```

Using a `tt` repetition, one can also forward arbitrary arguments to a callback.
Expand Down

0 comments on commit b31bb99

Please sign in to comment.