I'm preparing a 10-minute lightning talk on hygienic macros in rust (preview: I'm barely going to *mention* hygiene), and in the process, I've been surveying some of the Rust macros, and roughly categorizing them in terms of the "three canonical categories" that Matthias described--apologies if I'm misrepresenting him/you: - changing evaluation order, - implementing a data sublanguage, and - creating new binding forms.
Some of the Rust macros seem to fall into a fourth category, which arises from the fact that certain things are not expressions: - abstracting over things that are not expressions. For instance: cmp_impl!(impl Eq, eq, ne) cmp_impl!(impl TotalEq, equals) cmp_impl!(impl Ord, lt, gt, le, ge) cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering) Each of these expands into a top-level "impl" declaration, extending implementations of, e.g., Ord, from type T to type Ratio<T>. More generally, it seems to me that every time you constrain first-class-ness by making things not-first-class (e.g. module-level stuff in Racket), you will be required to use macros to abstract over these things. Thoughts? Back to writing my talk... John ____________________ Racket Users list: http://lists.racket-lang.org/users