DEV Community

dougfort
dougfort

Posted on

Simple Rust Macros:

I don't often think of macros as a resource in Rust. But I've been playing with a Rust substrate for Paul Graham's Bel dialect of Lisp.

/// Bel has four fundamental data types:
/// symbols, pairs, characters, and streams.
/// Instances of the four fundamental types are called objects
/// https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt
#[derive(Debug, PartialEq, Clone)]
pub enum Object {
    Symbol(String),
    Pair(Box<(Object, Object)>),
    Char(String),
    Stream,
}
Enter fullscreen mode Exit fullscreen mode

There's a lot of code like this:

Object::Pair(Object::Symbol("a".to_string()), Object::Symbol("nil".to_string()))
Enter fullscreen mode Exit fullscreen mode

In Rust for Rustaceans, Jon Gjengset says:

Declarative macros are primarily useful when you find yourself writing the same code over and over, and you'd like to, well, not do that.

So I added some simple macros. I got a lot of help from Rust by Example

/// nil object (aka 'false')
macro_rules! nil {
    () => {
        Object::Symbol("nil".to_string())
    };
}

/// 'true' object (true is not a good name for a macro)
macro_rules! t {
    () => {
        Object::Symbol("t".to_string())
    };
}

/// general symbol
macro_rules! symbol {
    ($n:expr) => {
        Object::Symbol($n.to_string())
    };
}

/// pair, probably part of a list
macro_rules! pair {
    ($a:expr, $b:expr) => {
        Object::Pair(Box::new(($a, $b)))
    };
}
Enter fullscreen mode Exit fullscreen mode

Now I write:

pair!(symbol!("a"), nil!())
Enter fullscreen mode Exit fullscreen mode

Much better, and not nearly as hard as I expected.

You can see the WIP code here

Top comments (1)

Collapse
 
chayimfriedman2 profile image
Chayim Friedman •

You should avoid macros as much as you can. All of your examples can be rewritten to use functions, and it is a much better approach (plus, it saves the ! keystroke!). Macros are needed when we want to perform some syntactical transformation otherwise impossible.