| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[R5RS] Creates a local scope where var … are bound to the value of expr …, then evaluates body …. vars must be symbols, and there shouldn't be a duplication. The value(s) of the last expression of body … becomes the value(s) of this form.
The three forms differ in terms of the scope exprs are evaluated.
Let evaluates exprs before (outside of) let form.
Let* evaluates exprs in the scope where vars before
it are bound. Letrec evaluates exprs in the environment
where vars are already bound (to an undefined value, initially).
letrec is necessary to define mutually recursive local procedures.
(define x 'top-x)
(let ((x 3) (y x)) (cons x y)) ⇒ (3 . top-x)
(let* ((x 3) (y x)) (cons x y)) ⇒ (3 . 3)
(let ((cons (lambda (a b) (+ a b)))
(list (lambda (a b) (cons a (cons b 0)))))
(list 1 2)) ⇒ (1 2 . 0)
(letrec ((cons (lambda (a b) (+ a b)))
(list (lambda (a b) (cons a (cons b 0)))))
(list 1 2)) ⇒ 3
|
A convenient macro when you have only one variable. Expanded as follows.
(let ((var expr)) body …) |
This macro simplifies the following idiom:
(let1 var expr (if var then else)) |
This macro simplifies the following idiom:
(let1 var expr body … var) |
[SRFI-2]
In short, it works like let*, but returns #f immediately
whenever the expression in bindings evaluates to #f.
Each binding should be one of the following form:
The expression is evaluated; if it yields true value, the value
is bound to variable, then proceed to the next binding. If
no more bindings, evaluates body …. If expression
yieds #f, stops evaluation and returns #f from and-let*.
In this form, variable is omitted. Expression is evaluated and the result is used just to determine whether we continue or stop further evaluation.
In this form, bound-variable should be an identifier denoting
a bound variable. If its value is not #f, we continue
the evaluation of the clauses.
Let's see some examples. The following code searches key from an assoc-list alist and returns its value if found.
(and-let* ((entry (assoc key alist))) (cdr entry)) |
If arg is a string representation of an exact integer, returns its value; otherwise, returns 0:
(or (and-let* ((num (string->number arg))
( (exact? num) )
( (integer? num) ))
num)
0)
|
The following is a hypothetical code that searches a certain server port number from a few possibilities (environment variable, configuration file, ...)
(or (and-let* ((val (sys-getenv "SERVER_PORT")))
(string->number val))
(and-let* ((portfile (expand-path "~/.server_port"))
( (file-exists? portfile) )
(val (call-with-input-string portfile port->string)))
(string->number val))
8080) ; default
|
A macro that emulates dynamic scoped variables.
Vars must be variables bound in the scope including
fluid-let form. Vals are expressions.
Fluid-let first evaluates vals, then
evaluates body …, with binding
vars to the corresponding values during the dynamic
scope of body ….
Note that, in multithreaded environment,
the change of the value of vars are visible from
all the threads. This form is provided mainly for
the porting convenience. Use parameter objects instead
(See section gauche.parameter - Parameters) for thread-local dynamic state.
(define x 0) (define (print-x) (print x)) (fluid-let ((x 1)) (print-x)) ⇒ ;; prints 1 |
[SRFI-8] This is the way to receive multiple values. Formals can be a (maybe-improper) list of symbols. Expression is evaluated, and the returned value(s) are bound to formals like the binding of lambda formals, then body … are evaluated.
(define (divrem n m) (values (quotient n m) (remainder n m))) (receive (q r) (divrem 13 4) (list q r)) ⇒ (3 1) (receive all (divrem 13 4) all) ⇒ (3 1) (receive (q . rest) (divrem 13 4) (list q rest)) ⇒ (3 (1)) |
See also call-with-values in Multiple values
which is the procedural equivalent of receive.
You can use define-values (See section Definitions) to
bind multiple values to the toplevel variables simultaneously.
Also let-values and let*-values
in SRFI-11 (srfi-11 - Let-values) provides
let-like syntax with multiple values.
[SRFI-31] A macro to evaluate an expression with recursive reference.
In the first form, evaluates expr while var in expr is bound to the result of expr. The second form is equivalent to the followings.
(rec name (lambda vars expr …)) |
Some examples:
;; constant infinite stream
(rec s (cons 1 (delay s)))
;; factorial function
(rec (f n)
(if (zero? n)
1
(* n (f (- n 1)))))
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Shiro Kawai on October, 7 2008 using texi2html 1.78.