Why is if a special form in Scheme?
ifbe implemented as a procedure that uses the
ifspecial form necessary in scheme, when the
condspecial form exists?
The need for special forms arises in general because of how procedures are evaluated in Scheme. R6RS the latest Scheme specification descibes how a procedure call is made section 9.1, Procedure calls:
When a procedure call is evaluated, the operator and operand expressions are evaluated (in an unspecified order) and the resulting procedure is passed the resulting arguments.
(if <test> <consequent> <alternate>)
Syntax: <test>, <consequent>,
and <alternate> must be expressions.
(if <test> <consequent>)
Semantics: An if expression is evaluated as follows: first, <test> is evaluated. If it yields a true value(see section 5.7), then <consequent> is evaluated and its values are returned. Otherwise <alternate> is evaluated and its values are returned. If <test> yields
#f and no <alternate> is specified, then the
result of the expression is unspecified.
i.e. unlike in a procedure call, not all parameters are evaluated.
Whether the <consequent> or lt;alternate>
parameter is evaluated depends on whether or not the evaluation of the
<test> paremeter results in the value
This behavior cannot be replicated with a procedure call. It needs special
support from the language interpreter/compiler.
(define (reciprocal n) (if (not (= 0 n)) (/ 1 n) #f))
Suppose we define if as a procedure as below:
(define (new-if predicate consequent alternative) (cond (predicate consequent) (else alternative)))
Suppose further that the =if= special form is replaced with the
new-if procedure as shown below:
(define (reciprocal n) (new-if (not (= 0 n)) (/ 1 n) #f))
Unlike the code that uses the
if special form, the code above
will fail with a divide by zero error. This is because the
new-if procedure is called only after its parameters are
(/ 1 n) is executed, resulting in a
Hence the need for
if to be a special form.
It could be argued that using some combination of quoting and lambdas,
one could make an if procedure. This wonderful
shows that if the inputs to the if conditional procedure are closures, one
could replace the if special form in Scheme (but not Lisp &emdash; the
difference boils down to lexical scoping used in Scheme vs dynamic scoping used in Lisp.) However, the syntactic inconvenience
would be so great that even Scheme defines
if as a special form.
if special form necessary, given that the
cond special form already exists? Not really. But the
convenience of the
if special form and the difficulty
of implementing it as a procedure may have caused the designers of
Scheme to make it a special form in the language.