#functional #proc-macro

macro functional_macro

A functional macro for Rust

2 releases

0.0.2 Dec 3, 2023
0.0.1 Dec 3, 2023

#729 in Procedural macros

MIT/Apache

15KB
344 lines

Functional Macro

Background

This macro is aimed to help enforce pure functions.

While it does have known limitations (see below), we still believe it provides value to help keep mutation in check.

How does it work?

  1. We parse each function arguments and check if they are mutable (&mut).
  2. We rewrite the function as with an internal module to prevent globals usage.

Original:

#[pure_functional]
fn foo(arg: i32) -> i32 {
    arg + 1
}

Rewrite:

fn foo(arg: i32) -> i32 {
    mod inner {
        pub fn foo(arg: i32) -> i32 {
            arg + 1
        }
    }
    inner::foo(arg)
}

Known Limitations

  1. Any struct that internally hides mutability will not be caught by this macro.

    For example, the following struct will not be caught by this macro:

    • Arc<Mutex<T>>.
    • Cell<T>.
    • RefCell<T>.
    • RwLock<T>.
    • UnsafeCell<T>.

    All of these wrap UnsafeCell<T> internally, which is why they are not caught by this macro.

  2. async functions are not supported.

  3. &self and &mut self are not supported.

Dependencies

~0.7–11MB
~67K SLoC