use tools.macro so that we can have docstrings and stuff