Next: Binding constructs, Previous: Assignments, Up: Core syntax [Contents][Index]
[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 #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, 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-expr may be any expression that yields one value. 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-expr is evaluated and its result is compared against each
datum. If the result of evaluating key-expr 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-expr is passed to proc, and its
result(s) is(are) returned from the case expression.
If the result of evaluating key-expr 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
no else
clause and the value of key-expr expression
doesn’t match any of datums provided in clauses.
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 unexpected value getting 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)
This is taken from Common Lisp.
Key-expr is a Scheme expression yielding one value. Each clause
must have either one of the following forms. The else
clause
can only appear as the last clause, if any.
(type-expr expr …) (else expr1 expr2 …)
Each type-expr must be a type expression (see Types and classes).
This macro first evaluates key-expr, then tests if its value is
of the type type-expr, in turn. If the type constraint is satisfied,
the expr … in the clause is evaluated and the last result(s)
becomes the value of typecase
. Type constrant is checked with
of-type?
(see Generic type predicates).
If none of the type constrait is
satisfied, exprs in the else
clause is evaluated if any,
or an undefined value results.
(typecase key-expr (<integer> 'a) ((</> <string> <symbol>) 'b)) ≡ (let ((tmp key-expr)) (cond ((of-type? tmp <integer>) 'a) ((of-type? tmp (</> <string> <symbol>)) 'b)))
Like typecase
, but if the value of key-expr
satisfies no type-expr and there’s no else
clause,
an error is signaled. If there’s an else
clause,
it is the same as typecase
.
(etypecase (sqrt -2) (<integer> 'int) (<real> 'real)) ⇒ *** ERROR: etypecase fell through: expecting one of types in (<integer> <real>), but got 0.0+1.4142135623730951i
[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
[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)
[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.
[SRFI-145] Evaluates text-expr and returns its value.
Also, this form declares the programmer’s intent that the code following this path always satisfy test-expr.
Currently, Gauche always signals an error
if text-expr evaluates to #f
.
(define (rsqrt x) (assume (and (real? x) (>= x 0))) (sqrt x)) gosh> (rsqrt -1) *** ERROR: Invalid assumption: (and (real? x) (>= x 0))
If optional arguments message obj … are passed, they
are given to the error
procedure when test-expr yields
false.
(define (rsqrt x) (assume (and (real? x) (>= x 0)) "Argument must be nonnegative real number, but got:" x) (sqrt x)) gosh> (rsqrt -1) *** ERROR: Argument must be nonnegative real number, but got: -1
Note: This form is advisory—it isn’t guaranteed for an error to be
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.
Evaluates expr, and Checks if the value has type type. If not, raises an error. The result of expr is returned.
As type, you can specify a Gauche class or a
descriptive type. The value is of type
if it satisfies (of-type? value type)
(see Types and classes).
If optional arguments message obj … are passed, they
are given to the error
procedure when test-expr yields
false.
(define (strlen s) (assume-type s <string>) (string-length s)) gosh> (strlen 4) *** ERROR: s is supposed to be of type #<class <string>>, but got 4 (define (strlen s) (assume-type s <string> "Argument s must be a string, but got:" s) (string-length s)) gosh> (strlen 4) *** ERROR: Argument s must be a string, but got: 4
The type assumption may be used by the compiler future compilers for optimizations. In order for the compiler to use the type constraint information, type must be an expression statically computable at compile-time. That is, it must be either a class or a type constructor expression, or a constant binding to them.
Note: Like assume
, this form is advisory; it is not guaranteed
that the check is performed, nor expr is evaluated.
Next: Binding constructs, Previous: Assignments, Up: Core syntax [Contents][Index]