6. Bigloo -- Pattern Matching

Browsing
Home: | Bigloo A ``practical Scheme compiler'' User manual for version 2.6b December 2003
Previous chapter: | Standard Library
Next chapter: | Object System
Pattern Matching
6.1 | Bigloo pattern matching facilities
6.2 | The pattern language
Chapters
| Acknowledgements
1. | Table of contents
2. | Overview of Bigloo
3. | Modules
4. | Core Language
5. | Standard Library
6. | Pattern Matching
7. | Object System
8. | Threads
9. | Regular parsing
10. | Lalr(1) parsing
11. | Errors and Assertions
12. | Eval and code interpretation
13. | Macro expansion
14. | Command Line Parsing
15. | Explicit typing
16. | The C interface
17. | The Java interface
18. | Bigloo Libraries
19. | Extending the Runtime System
20. | SRFIs
21. | DSSSL support
22. | Compiler description
23. | User Extensions
24. | Bigloo Development Environment
25. | Global Index
26. | Library Index
| Bibliography
| Pattern matching is a key feature of most modern functional programming languages since it allows clean and secure code to be written. Internally, ``pattern-matching forms'' should be translated (compiled) into cascades of ``elementary tests'' where code is made as efficient as possible, avoiding redundant tests; Bigloo's ``pattern matching compiler'' provides this. The technique used is described in details in [QueinnecGeffroy92], and the code generated can be considered optimal not in structures for the moment.10 due to the way this ``pattern compiler'' was obtained. The ``pattern language'' allows the expression of a wide variety of patterns, including: Non-linear patterns: pattern variables can appear more than once, allowing comparison of subparts of the datum (through `eq?`) Recursive patterns on lists: for example, checking that the datum is a list of zero or more `a`s followed by zero or more `b`s. Pattern matching on lists as well as on vectors or structures.
6.1 Bigloo pattern matching facilities
Only two special forms are provided for this in Bigloo: `match-case` and `match-lambda`.
match-case key clause... | bigloo syntax
The argument `key` may be any expression and each `clause` has the form
    (pattern s-expression...)

Semantics: A `match-case` expression is evaluated as follows. `key` is evaluated and the result is compared with each successive pattern. If the pattern in some `clause` yields a match, then the expressions in that `clause` are evaluated from left to right in an environment where the pattern variables are bound to the corresponding subparts of the datum, and the result of the last expression in that `clause` is returned as the result of the `match-case` expression. If no `pattern` in any `clause` matches the datum, then, if there is an `else` clause, its expressions are evaluated and the result of the last is the result of the whole `match-case` expression; otherwise the result of the `match-case` expression is unspecified.
The equality predicate used is `eq?`.

    (match-case '(a b a)
       ((?x ?x) 'foo)
       ((?x ?- ?x) 'bar))
       => bar

The following syntax is also available:

match-lambda clause... | bigloo syntax
It expands into a lambda-expression expecting an argument which, once applied to an expression, behaves exactly like a `match-case` expression.
    ((match-lambda
       ((?x ?x) 'foo)
       ((?x ?- ?x) 'bar))
     '(a b a))
       => bar

6.2 The pattern language

The syntax for <pattern> is:

    <pattern> ==>                Matches:

      <atom>                    the <atom>.
    | (kwote <atom>)            any expression eq? to <atom>.
    | (and <pat1> ... <patn>)   if all of <pati> match.
    | (or <pat1> ... ...<patn>) if any of <pat1> through <patn> matches.
    | (not <pat>)               if <pat> doesn't match.
    | (? <predicate>)           if <predicate> is true.
    | (<pat1> ... <patn>)       a list of n elements. Here, ... is a
                                meta-character denoting a finite repetition
                                of patterns.
    | <pat> ...                 a (possibly empty) repetition
                                of <pat> in a list.
    | #(<pat> ... <patn>)       a vector of n elements.
    | #{<struct> <pat> ... }    a structure.
    | ?<id>                     anything, and binds id as a variable.
    | ?-                        anything.
    | ??-                       any (possibly empty) repetition of anything
                                in a list.
    | ???-                      any end of list.

Remark: `and, or, not, check` and `kwote` must be quoted in order to be treated as literals. This is the only justification for having the `kwote` pattern since, by convention, any atom which is not a keyword is quoted.

#### Explanations through examples

- `?-` matches any s-expr
- `a` matches the atom `'a`.
- `?a` matches any expression, and binds the variable `a` to this expression.
- `(? integer?)` matches any integer
- `(a (a b))` matches the only list `'(a (a b))`.
- `???-` can only appear at the end of a list, and always succeeds. For instance, `(a ???-)` is equivalent to `(a . ?-)`.
- when occurring in a list, `??-` matches any sequence of anything: `(a ??- b)` matches any list whose `car` is `a` and last `car` is `b`.
- `(a ...)` matches any list of `a`'s, possibly empty.
- `(?x ?x)` matches any list of length 2 whose `car` is eq to its `cadr`
- `((and (not a) ?x) ?x)` matches any list of length 2 whose `car` is not eq to `'a` but is eq to its `cadr`
- `#(?- ?- ???-)` matches any vector whose length is at least 2.
- `#{foo (?- . ?-) (? integer?)}` matches any structure `foo` whose first and second fields are respectively a pair and an integer. You can provide only the fields you want to test. The order is not relevant.

Remark: `??-` and `...` patterns can not appear inside a vector, where you should use `???-`: For example, `#(a ??- b)` or `#(a...)` are invalid patterns, whereas `#(a ???-)` is valid and matches any vector whose first element is the atom `a`.

10: In the cases of pattern matching in lists and vectors,

This Scribe page has been generated by `scribeinfo`.
Last update Tue Dec 16 13:46:41 2003