Reputation: 13
When COND
is given only one test clause and nothing else at all it always returns the test result:
CL-USER> (cond (t))
T
CL-USER> (cond ((> 5 10)))
NIL
Isn't COND
just a way to write IF
statements?
This doesn't hold for this as when rewriting COND
with test only:
CL-USER> (if (> 5 1))
error while parsing arguments to DESTRUCTURING-BIND:
too few elements in
((> 5 1))
to satisfy lambda list
(SB-IMPL::TEST SB-IMPL::THEN &OPTIONAL SB-IMPL::ELSE):
between 2 and 3 expected, but got 1
If it is this way then how does COND
exactly transform every clause into IF
version?
Upvotes: 1
Views: 171
Reputation: 85853
When COND is given only one test clause and nothing else at all it always returns the test result:
That's right. According to the HyperSpec entry on cond:
results---the values of the forms in the first clause whose test-form yields true, or the primary value of the test-form if there are no forms in that clause, or else nil if no test-form yields true.
Isn't COND just a way to write IF statements?
Well, cond is declared to be a macro, and if to be a special operator, so you can think of it that way, although the expansion of cond isn't defined specifically. But if is defined with syntax that requires a then-part, whereas cond isn't. Here's what a cond clause with no forms expands to (in SBCL):
CL-USER> (pprint (macroexpand '(cond ((+ 2 3)))))
(LET ((#:G1013 (+ 2 3)))
(IF #:G1013
#:G1013
(COND)))
The value of the form is saved in a value and then used as the then-part. When there are forms in the clause, they're wrapped in a progn (which returns the value of its last form):
CL-USER> (pprint (macroexpand
'(cond
((= 2 3) 42 78)
((+ 2 3))
((= 4 5) (print 'something-else)))))
(IF (= 2 3)
(PROGN 42 78)
(COND ((+ 2 3)) ((= 4 5) (PRINT 'SOMETHING-ELSE))))
Upvotes: 2