 As we've briefly discussed earlier, a macro is a special kind of function. When called in our code, a macro takes its arguments as raw reader data, and the reader data returned by the macro call gets inserted in place of the macro call itself. For creating macros, closure.core contains a macro called def macro. Here we create a very simple macro called if not. This macro function has two parameters, condition and expression. The list function in its body returns a new list containing its arguments, so this macro returns a list with a symbol if, the value of condition, the value nil, and the value of expression. So this call to the if not macro is passed two un-evaluated lists, one starting with a symbol greater than and then the numbers three and five, and the other list has a symbol print and a string high. And then this macro call returns if greater than three five nil print high. This new list returned from the macro replaces the macro call and is evaluated in its place. Effectively, this if not macro we've created works like an if with one expression after the condition, except if not evaluates the expression when the condition is false rather than true. Now to make if not a more complete opposite of the if special form, it should also work for two expressions after the condition. We can give the macro multiple erities just like we can with a regular function. Here we added an erity with three parameters, where the parameters expression two and expression three get reversed in the returned if form. So now we can use if not with two expressions, they get their position swapped in the returned if form. So this macro call here returns an if form with the same condition, but with the two expressions in reverse position. Though this example if not macro is reductively simple and so not very useful, it does demonstrate the basic pattern of a macro. The macro takes input reader data and somehow transcludes it into some kind of code template. We'll go a little deeper into writing more complex macros, but it's important to make clear that while you should feel comfortable using the macros provided by the language and APIs, you should feel under no obligation to create macros yourself. Macros are for extending and refining the syntax of the base language, which is not something we should be doing in most application programming. As powerful as they can be, macros have two big downsides. First because macros are written to process source code at compile time, it wouldn't make sense to treat them as values like we do with regular functions. In fact, the evaluator throws an exception if you attempt to use a macro as a value. The second big problem with macros is that because they can rearrange and supplement code in strange ways, a reader unfamiliar with particular macros will have difficulty reading code that uses them. Every closure programmer becomes familiar with the standard library macros as they learn the language, but when code uses many custom macros, even experienced closure programmers may get confused. So you should definitely prefer regular functions over macros. Only if you're attempting to extend the language with a library or framework should you seriously consider creating macros yourself. You may have need to generate unique symbols. The genSim function generates a symbol that ends in a numbered name that is guaranteed to be generated only once within the run of the program. By default, the number is prefixed with g underscore, but you can specify a different prefix. Here this called the genSim with no argument returns some symbol starting with capital g underscore followed by some integer number that has not been previously generated. GenSim called with this argument string foo returns a symbol starting with the character's f-o-o followed by some integer that has not been previously generated. So why would we want to use genSim? Well the genSim function is useful in macros that return forms defining local variables. If a macro returns say an fn form that defines a parameter foo, this foo might conflict with another foo defined in the context of where the macro is used. For example, in the second macro call the argument foo is supposed to resolve to something in the context of the macro call, but because the macro encloses foo in an fn form defining its own local foo, the foo of the call gets erroneously resolved to this local parameter. To fix this, we use genSim to name the local variable in the form returned from the macro. Now each time we call the macro, it generates a symbol name that isn't used anywhere else in code, assuming that is we don't name any symbols in the format g underscore x and why would you do that? So any symbol we pass into the macro won't conflict with any symbol created by the macro. If a macro returns a symbol in its reader data that doesn't represent a local binding, that symbol is resolved in the context of where the macro is called. What we generally want, however, is for the returned symbols to resolve in the current namespace of where the macro is defined. We can fix this problem simply by fully qualifying every non-local symbol of a returned forms. Here for example, if the symbol ted in the returned form of this macro is supposed to resolve to ted of the cate namespace, we should fully qualify the symbol. A less cumbersome way to fix this problem, though, is to use what's called syntax quoting. Syntax quoting, however, is a little complicated and we won't be creating our own macros in the rest of this course, so we won't cover syntax quoting here. If you do ever try writing your own macros, though, keep in mind that syntax quoting makes certain macro tasks much easier.