;;;; A package that declares macros. ;;;; ;;;; Its names arrive at an importer qualified, exactly as a defn's do: the ;;;; program that imports this directory as [mac] writes (mac/twice 4), and ;;;; (twice 4) is an unknown name there. Nothing becomes globally visible by ;;;; importing a package, macros included. ;;;; ;;;; Inside the package the names are the package's own, unqualified, which is ;;;; the same rule every other declaration here follows. (defn double [n i32] i32 (* n 2)) ;; The plain case: one macro, nothing else needed to compile it. (defmacro twice [args] `(+ ~(at args 0) ~(at args 0))) ;; A macro that quasiquotes a call to another macro of this package. That is ;; *output*, not a compile-order dependency -- the call is part of what this ;; macro answers and is expanded again after it returns -- so it needs nothing ;; compiled first. What it does need is the name coming out qualified, because ;; the answer lands in the importer's file, where [twice] is not a name. (defmacro quad [args] `(twice (twice ~(at args 0)))) ;; And one whose output names a *function* of this package, which has the same ;; problem and the same answer. (defmacro doubled [args] `(double ~(at args 0))) ;; [wrap] takes a form-valued expression and answers one, so it is a macro ;; another macro's *body* can call for real. (defmacro wrap [args] `(do ~(at args 0))) ;; A macro that really calls another, outside a quasiquote. This one *is* a ;; compile-order dependency: [wrap] has to be compiled and loaded before this ;; body will compile at all, which is what the rounds in [Macro] are for, and ;; it is the case a quasiquoted call deliberately is not. (defmacro also-twice [args] (wrap `(+ ~(at args 0) ~(at args 0)))) ;; A shadowing local named like a top-level of this package. The rename must ;; leave it alone, or the expansion would name [mac/double] where the author ;; wrote a let binding. (defmacro shadowed [args] `(let [double ~(at args 0)] (+ double 1))) ;; The package's own function, calling the package's own macro unqualified. (defn quadruple [n i32] i32 (quad n))