While most operations in Scheme are procedure calls, there are a few other kinds of expressions you need to know about, which behave differently. They are called special forms.
Procedure calls and special forms are syntactically similar--both
are a sequence of syntactic units between parentheses, e.g.,
(foo bar baz). They are semantically very different, however,
which is why you need to know the special forms, and not mistake
them for procedures.
If the first thing after the left parentheses is a keyword that
names a special form, like
does something special for that kind of expression. If it's
not, Scheme recognizes the expression in parentheses as a procedure
call, and evaluates it in the usual way for procedure calls.
(The fact that special forms are evaluated in a way different from procedure calls is why they are called "special forms"---Scheme recognizes some kinds of compound expressions as needing special treatment, rather than just being procedure calls.)
You've already seen two of the five or six important special forms,
define and the assignment operator
set! isn't a procedure, because
its first argument is not really an expression to be evaluated in the
normal way, to get a value to pass as an argument. It's the name of a
place to put a value. (e.g., if we say
(set! a b), we
get the value of
b, and put it into the storage named by
define treats its first argument specially--the name
of a variable or procedure isn't an expression that is evaluated and
define---it's just a name, and you're telling
to allocate some storage and use that name for it.
Other special forms we'll see include
caseand the short-circuiting logical operators
letand its variants
quasiquote, which let you write complex data structures as textual literals in your code, and
lambda, which creates new procedures in a very useful way.
There is also a few very special special forms,
which let you define your own special forms as "macros."