Next: Binding constructs, Previous: Assignments, Up: Core syntax [Contents][Index]

- Special Form:
**if***test consequent alternative* - Special Form:
**if***test consequent* [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`

- Special Form:
**cond***clause1 clause2 …* [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`expr`s 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`#f`

, 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,

`expr`s 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

- Special Form:
**case***key clause1 clause2 …* [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`datum`s 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 (using`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`

- Macro:
**ecase***key clause1 clause2 …* This works exactly like

`case`

, except when there’s no`else`

clause and the value of`key`expression doesn’t match any of`datum`s provided in`clause`s. While`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)

- Special Form:
**and***test …* [R7RS base] 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

- Special Form:
**or***test …* [R7RS base] 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)

- Special Form:
**when***test expr1 expr2 …* - Special Form:
**unless***test expr1 expr2 …* [R7RS base] 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.

- Macro:
**assume***test-expr message …* [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`real-sqrt`

code, 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.

- Macro:
**assume-type***expr type* Check if the value of expression

`expr`has type`type`. If not, raises an error.(assume-type expr type) ≡ (assume (is-a? expr type))

Note: Like

`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.

Next: Binding constructs, Previous: Assignments, Up: Core syntax [Contents][Index]