Macros serve lots of purposes. One is providing convenient syntax.
(loop for i from 10 below 100 step 3
when (evenp i)
collect i)
Above is using the LOOP macro, which implements a lot of syntax for various ways to LOOP. The syntax description is actually quite long:
See the EBNF description of the LOOP macro in the standard:
http://www.lispworks.com/documentation/HyperSpec/Body/m_loop...
There are other syntactic forms which use more parentheses. For example the DEFCLASS macro. The basic EBNF syntax for DEFCLASS is:
defclass class-name ({superclass-name}*) ({slot-specifier}*) [[class-option]]
slot-specifier::= slot-name | (slot-name [[slot-option]])
slot-name::= symbol
slot-option::= {:reader reader-function-name}* |
{:writer writer-function-name}* |
{:accessor reader-function-name}* |
{:allocation allocation-type} |
{:initarg initarg-name}* |
{:initform form} |
{:type type-specifier} |
{:documentation string}
function-name::= {symbol | (setf symbol)}
class-option::= (:default-initargs . initarg-list) |
(:documentation string) |
(:metaclass class-name)
The DEFCLASS macro implementation will check some of that automatically, but much of the syntax has to be check by the macro in the implementation code.
> we can still think of them as special procedure calls
That's not a good idea. It's misleading.