A nice example is `match` that is one of the macros that comes by default in Racket.
#lang racket
(define (show x)
(match x
[(vector a b c)
(display "It's a vector, total = ")
(displayln (+ a b c))]
[(list p q)
(display "I's a list, average = ")
(displayln (/ (+ p q) 2))]))
(show (list 8 2))
(show (vector 1 2 3))
(Playable version
http://pasterack.org/pastes/75154 )
The idea is that `match` can analyze the value of the first argument (`x` in this case) and then it binds the variables (a,b,c or p,q in this case).
In this case I'm matching only a vector with 3 values or a list with 2 values, but you can match more complicated and nested pattern.
The interesting part is that inside match you have the full power of the language, you are not restricted to a few special hardcoded cases (like `display`). You can send an hppt request, play a sound, save a value to disk, calculate the prime factorization, transform the text to uppercase, anything that is available in the language is available inside match.
But `match is just a normal macro. Racket is implemented in layers. The bottom layer is implemented currently in C, but it doesn't define `match`. The bottom layer is almost hidden and it is used to define some libraries and an intermediate language that it is used to define some libraries and an intermediate language, ..., and after a few steps you get the official Racket language.
But if you like you can reimplement a macro like `match`, or a variant, or your own macro, with all the magic to define local variables and use all the power of the language inside it.