jackfirth
This package provides a Racket syntax for guard statements. A guard statement ensures that condition is true before executing statements after the guard. Boolean conditions can be checked with guard , and pattern matching conditions can be checked with guard-match . Guard statements can only be used within guarded blocks, which are either uses of the guarded-block macro or bodies of functions defined with define/guard .
Guard statements allow writing code linearly when it would ordinarily require deep nesting of forms like cond and match . Compare the following two function definitions, one of which uses traditional Racket forms and the other of which uses guard statements.
Guard statements cooperate with macro expansion. Macros can expand into uses of guard and guard-match . Such user-defined guard statements are recognized by guarded-block and define/guard via local expansion.
syntax
( guard condition-expr#:elsefail-body...+)
condition-expr : any/c
> (add-positive-47)'nonpositive-x
> (add-positive4-7)'nonpositive-y
> (add-positive47)11
syntax
( guard-match match-patternexpr#:elsefail-body...+)
expr : any/c
'("jump, dog!" "dig, mole!" "hop, rabbit!")
Additionally, multiple patterns may be given in place of match-pattern using values . This causes the guard to expect expr to evaluate to multiple values, one per given pattern, or else an error is raised. Each value is matched against the corresponding pattern, and if any of them do not match, the fail-body... branch is taken. This form is similar to match-define-values .
#:else'())'("jump, dog!" "dig, mole!" "hop, rabbit!")
syntax
( define/guard (headargs)body...+)
head = id| (headargs)args = arg...| arg....rest-idarg = arg-id| [arg-iddefault-expr]| keywordarg-id| keyword[arg-iddefault-expr]
(filter-and-double-numbersrest-xs))'(2 4 6 8 10)
syntax
( guarded-block body...+)