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

clauseis evaluated in turn, and if`#f`

is obtained then evaluation stops and`#f`

is returned. If all are non-`#f`

thenbodyis evaluated and the last form gives the return value, or ifbodyis empty then the result is`#t`

. Eachclauseshould be one of the following,

`(symbol expr)`

- Evaluate
expr, check for`#f`

, and bind it tosymbol. Like`let*`

, that binding is available to subsequent clauses.`(expr)`

- Evaluate
exprand check for`#f`

.`symbol`

- Get the value bound to
symboland 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`=>`

.