Next: , Previous: SRFI-1, Up: SRFI Support

6.4.4 SRFI-2 - and-let*

The following syntax can be obtained with

     (use-modules (srfi srfi-2))
— library syntax: and-let* (clause ...) body ...

A combination of and and let*.

Each clause is evaluated in turn, and if #f is obtained then evaluation stops and #f is returned. If all are non-#f then body is evaluated and the last form gives the return value, or if body is empty then the result is #t. Each clause should be one of the following,

(symbol expr)
Evaluate expr, check for #f, and bind it to symbol. Like let*, that binding is available to subsequent clauses.
Evaluate expr and check for #f.
Get the value bound to symbol and check for #f.

Notice that (expr) has an “extra” pair of parentheses, for instance ((eq? x y)). One way to remember this is to imagine the symbol in (symbol expr) is omitted.

and-let* is good for calculations where a #f value means termination, but where a non-#f value is going to be needed in subsequent expressions.

The following illustrates this, it returns text between brackets ‘[...]’ in a string, or #f if there are no such brackets (ie. either string-index gives #f).

          (define (extract-brackets str)
            (and-let* ((start (string-index str #\[))
                       (end   (string-index str #\] start)))
              (substring str (1+ start) end)))

The following shows plain variables and expressions tested too. diagnostic-levels is taken to be an alist associating a diagnostic type with a level. str is printed only if the type is known and its level is high enough.

          (define (show-diagnostic type str)
            (and-let* (want-diagnostics
                       (level (assq-ref diagnostic-levels type))
                       ((>= level current-diagnostic-level)))
              (display str)))

The advantage of and-let* is that an extended sequence of expressions and tests doesn't require lots of nesting as would arise from separate and and let*, or from cond with =>.