{$define <identifier> := <some complex expression>}

After that, every time the compiler sees that identifier it treats it as that complex expression. Not a much by itself, but when combined with conditional compiler directives macro can become a very powerful tool.

I, for example, built with their help something akin to generics in FPC 1.1 (there wasn't even 1.9 yet!) . Of course, handling it all is a pain, compiler (at least its earlier versions) could not pinpoint the error location properly if macros are involved, the code completion in Lazarus died trying to parse that stuff... But it worked, and helped me a lot.