- (bind pat seq (where fender ...) .. xpr ....)syntax
Here, a pattern, pat, is a nested psudolist of (mostly) symbols, seq a sequencce expression, i.e. a mixture of pseudolists, vectors and strings, fender a check expression on pattern variables, var, of the form (var ok? ...) and xpr .... constitute the body of the macro. Note the special use of dots here and below: Three dots repeat the expression to the left zero or many times, two dots zero or one times and four dots one or many times.
This macro binds pattern variables, i.e. symbols of pat, to corresponding sequenceds of seq, checks, if the fenders succeed and exectutes the body in this context.
There are some features, which I would like to have and which are implemented as well. First wildcards, represented by the underscore symbol. It matches everything, but binds nothing. So it can appear multiple times in the same macro. Wildcard symbols are simply not collected in the internal destructure routine.
Second, non-symbol literals, which don't bind anything, of course, but match only expressions evaluating to themselves.
The last feature missing is fenders, which is important in particular for bind-case and can easily be implemented with a where clause: A pattern matches successfully if only each pattern variable can be bound and the checks as well as the fenders are satisfied. If the where clause doesn't pass, the next pattern is tried in bind-case or a seq-exception is signalled in bind.
This version of the library is a complete rewrite. The code no longer uses Graham's dbind implementation. Instead, a direct implementation of bind is given, which doesn't need gensyms. The internal destructure routine transforms the pattern and sequence arguments into three lists, pairs, literals and tails. Pairs is a list of pattern-variable and corresponding sequence-accesscode pairs to be used in a let at runtime, literals and tails check for equality of literals and their corresponding sequence values, and the emptyness of sequence tails corresponding to null patterns respectively. So, contrary to Graham's dbind, an exception is raised if the lengths of a pattern and its corresponding sequence don't match. Fenders are supplied in a where clause at the very beginning of the macro body: A list of pattern-variable predicates pairs is internally transformed into a list of predicate calls.
The latest addition to the library are algebraic types, to be accessed via the binding macros, thus making e.g. define-concrete-type obsolete.