[R7RS base] Test is evaluated. If it yields a true value, consequent is evaluated. Otherwise, alternative is evaluated. If alternative is not provided, it results undefined value.
(if (number? 3) 'yes 'no) ⇒ yes (if (number? #f) 'yes 'no) ⇒ no (let ((x '(1 . 2))) (if (pair? x) (values (car x) (cdr x)) (values #f #f))) ⇒ 1 and 2
[R7RS+ base][SRFI-61] Each clause must be the form
(test expr …) (test => expr) (test guard => expr) (else expr expr2 …)
The last form can appear only as the last clause.
cond evaluates test of each clauses in order, until
it yields a true value. Once it yields true, if the clause
is the first form, the corresponding exprs are evaluated
and the result(s) of last expr is(are) returned; if the clause
is the second form, the expr is evaluated and it must yield
a procedure that takes one argument. Then the result of test
is passed to it, and the result(s) it returns will be returned.
The third form is specified in SRFI-61. In this form, test
can yield arbitrary number of values. The result(s)
of test is(are) passed to guard; if it returns a true value,
expr is applied with an equivalent argument list, and its
result(s) is(are) returned. If guard returns
the evaluation proceeds to the next clause.
If no test yields true, and the last clause is not the fourth form (else clause), an undefined value is returned.
If the last clause is else clause and all tests are failed, exprs in the else clause are evaluated, and its last expr’s result(s) is(are) returned.
(cond ((> 3 2) 'greater) ((< 3 2) 'less)) ⇒ greater (cond ((> 3 3) 'greater) ((< 3 3) 'less) (else 'equal)) ⇒ equal (cond ((assv 'b '((a 1) (b 2))) => cadr) (else #f)) ⇒ 2
[R7RS+ base][SRFI-87] Key may be any expression. Each clause should have the form
((datum ...) expr expr2 …) ((datum ...) => proc)
where each datum is an external representation of some object. All the datums must be distinct. The last clause may be an “else clause,” which has the form
(else expr expr2 …) (else => proc)
First, key is evaluated and its result is compared against each
datum. If the result of evaluating key is equivalent
eqv?, see Equality), to a datum,
then the expressions in the corresponding clause are evaluated
sequentially, and the result(s) of the last expression in the
clause is(are) returned from the case expression.
The forms containing
=> are specified in SRFI-87. In these
forms, the result of key is passed to proc, and its
result(s) is(are) returned from the case expression.
If the result of evaluating key is different from every datum, then if there is an else clause its expressions are evaluated and the result(s) of the last is(are) the result(s) of the case expression; otherwise the result of the case expression is undefined.
(case (* 2 3) ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite)) ⇒ composite (case (car '(c d)) ((a) 'a) ((b) 'b)) ⇒ undefined (case (car '(c d)) ((a e i o u) 'vowel) ((w y) 'semivowel) (else 'consonant)) ⇒ consonant (case 6 ((2 4 6 8) => (cut + <> 1)) (else => (cut - <> 1))) ⇒ 7 (case 5 ((2 4 6 8) => (cut + <> 1)) (else => (cut - <> 1))) ⇒ 4
This works exactly like
case, except when there’s
else clause and the value of key expression
doesn’t match any of datums provided in clauses.
case form returns undefined value for such case,
ecase raises an error.
It is taken from Common Lisp. It’s a convenient form when you want to detect when unexpected value is passed just in case.
(ecase 5 ((1) 'a) ((2 3) 'b) ((4) 'c)) ⇒ ERROR: ecase test fell through: got 5, expecting one of (1 2 3 4)
The test expressions are evaluated from left to right,
and the value of the first expression that evaluates to a false
value is returned.
Any remaining expressions are not evaluated.
If all the expressions evaluate to true values,
the value of the last expression is returned.
If there are no expressions then
#t is returned.
(and (= 2 2) (> 2 1)) ⇒ #t (and (= 2 2) (< 2 1)) ⇒ #f (and 1 2 'c '(f g)) ⇒ (f g) (and) ⇒ #t
The test expressions are evaluated from left to right,
and the value of the first expression that evaluates to a true
value is returned. Any remaining expressions are not evaluated.
If all expressions evaluate to false values, the value of the
last expression is returned. If there are no expressions then
#f is returned.
(or (= 2 2) (> 2 1)) ⇒ #t (or (= 2 2) (< 2 1)) ⇒ #t (or #f #f #f) ⇒ #f (or (memq 'b '(a b c)) (/ 3 0)) ⇒ (b c)
Evaluates test. If it yields true value (or false in case of
unless), expr1 and expr2 … are evaluated
sequentially, and the result(s) of the last evaluation is(are) returned.
Otherwise, undefined value is returned.
[SRFI-145] This declares the programmer’s intent that the code following this path always satisfy test-expr.
Currently, Gauche evaluates test-expr, and if it evaluates to false, an error is signalled.
(define (real-sqrt x) (assume (and (real? x) (>= x 0))) (sqrt x)) gosh> (real-sqrt -1) *** ERROR: Invalid assumption: (and (real? x) (>= x 0))
Note: This form is advisory—test-expr isn’t guaranteed to be
evaluated, nor it isn’t guaranteed for an error is signaled when
test-expr fails. For example, we may add an optimization
option that omits testing in speed-optimized code in future.
We may also enhance the compiler to generate better code using the
given information—for example, in the above
the compiler could theoretically deduce that
(sqrt x) only needs to
work as real functions, so it would be able to generate specialized code.
Use this form to inform the compiler and the reader your intention.
Check if the value of expression expr has type type. If not, raises an error.
(assume-type expr type) ≡ (assume (is-a? expr type))
assume, this form is advisory; it is not guaranteed
that the check is performed, nor expr is evaluated.
On the other hand, the type assumption may be used by the compiler future compilers for optimizations.