Looking through how Chicken compiler works, it seems that Chicken detects syntax-case and friends, performing them at compile-time, However if a macro needs to use a function, the function should be defined using define-for-syntax. Perhaps our rules for macros:
1. Should be defined using 'mac
2. Any form that has a 'mac will be executed at compile-time, with the 'mac transformed to a macro definition:
An extra hash argument can implement both optional and named args. Representing optional args as varargs would complicate the source transformation when they are used simultaneously in the same function.
Edit: My approach appears to be somewhat similar to what pg did in the Scheme version - cref ac-fn, ac-complex-fn, ac-complex-args, ac-complex-opt in ac.scm
Since code is spec (grumble) I think it might be better to follow mostly what pg did, although I dunno, not sure ^^. How can passing in a hash table seamlessly emulate the same functionality while improving performance?