# Overview

This package is a dependable match macro library for chez scheme. This macro is hacked from Alex Shinn's famous match macro (http://synthcode.com/scheme/match.scm). However, Alex's code lacks some tests and is not fully portable to chez scheme. My purpose is making this library easily imported into other code.

This package is published with Akku(https://akkuscm.org/), which is a language package manager for Scheme. 

This package has been tested with Chez Scheme versions 9.4 and 9.5.

This package is also referenced to https://github.com/fedeinthemix/chez-matchable.

# Changelog

## 1.1.0

- Added `:=` as an exported alias for the `=` pattern keyword.  This lets
  users write `(match x ((:= proc pat) ...))` when the surrounding import
  context provides a different binding for `=` (for example, when only
  `(chezscheme)` is imported).  See "The `:=` alias for `=` patterns" below.

## 1.0.1

- Improved performance of record matching (`$` and `&` patterns) by caching
  `record-accessor` and `record-mutator` procedures per record type and field.
- Migrated `tests/test-match-syntax-error.sps` to SRFI-64 testing form.
- Added a performance benchmark suite (`tests/bench-ufo-match.sps`) and
  recorded baseline results (`doc/bench-ufo-match-results.md`).

# Some Revision
1. Some procedure references in test are replaced. Like square, I replace it with sqrt for chez scheme.
2. The @ operator is used for matching record types. However, it's not portable to chez scheme. And I replace it with &.

# API
Detailed Usage please refer to tests/test-ufo-match.sps.
1. (match expr (pattern (=> failure) . body) ...)
2. match-lambda 
3. match-lambda* 
4. match-let 
5. match-let* 
6. match-letrec
7. match-named-let

# The `:=` alias for `=` patterns

The `=` pattern applies a procedure to the value being matched and then
matches the result against a sub-pattern:

```scheme
(match '(a b c)
  ((= car x) x))
;; => a
```

Because `=` is a common procedure name, its binding can differ depending on
which libraries are imported.  In Chez Scheme, `(rnrs base)` and
`(chezscheme)` export `=` bindings that are not `free-identifier=?`.  When
`ufo-match` is used in a context where the visible `=` comes from a different
library than `(rnrs base)`, the `=` pattern may be silently misinterpreted
as an ordinary list/pair pattern.

To avoid this, `ufo-match` also exports `:=` as an auxiliary keyword.  It
behaves exactly like `=` but always carries the binding from `(ufo-match)`:

```scheme
(import (chezscheme) (ufo-match))

(match '(a b c)
  ((:= car x) x))
;; => a
```

Use `:=` whenever `=` might be shadowed or imported from a non-R6RS library.

# Test
API 2-7 haven't been tested.
> bash test.sh 

# Alex Shinn's Notes

The implementation is a simple generative pattern matcher - each pattern is expanded into the required tests, calling a failure continuation if the tests fail.  This makes the logic easy to follow and extend, but produces sub-optimal code in cases where you have many similar clauses due to repeating the same tests.  Nonetheless a smart compiler should be able to remove the redundant tests.  For MATCH-LET and DESTRUCTURING-BIND type uses there is no performance hit.  The original version was written on 2006/11/29 and described in the following Usenet post:
  http://groups.google.com/group/comp.lang.scheme/msg/0941234de7112ffd
and is still available at
  http://synthcode.com/scheme/match-simple.scm
It's just 80 lines for the core MATCH, and an extra 40 lines for MATCH-LET, MATCH-LAMBDA and other syntactic sugar.

A variant of this file which uses COND-EXPAND in a few places for performance can be found at http://synthcode.com/scheme/match-cond-expand.scm

2021/06/21 - fix for `(a ...)' patterns where `a' is already bound (thanks to Andy Wingo)
2020/09/04 - perf fix for `not`; rename `..=', `..=', `..1' per SRFI 204
2020/08/21 - fixing match-letrec with unhygienic insertion
2020/07/06 - adding `..=' and `..=' patterns; fixing ,@ patterns
2016/10/05 - treat keywords as literals, not identifiers, in Chicken
2016/03/06 - fixing named match-let (thanks to Stefan Israelsson Tampe)
2015/05/09 - fixing bug in var extraction of quasiquote patterns
2014/11/24 - adding Gauche's `@' pattern for named record field matching
2012/12/26 - wrapping match-let&co body in lexical closure
2012/11/28 - fixing typo s/vetor/vector in largely unused set! code
2012/05/23 - fixing combinatorial explosion of code in certain or patterns
2011/09/25 - fixing bug when directly matching an identifier repeated in the pattern (thanks to Stefan Israelsson Tampe)
2011/01/27 - fixing bug when matching tail patterns against improper lists
2010/09/26 - adding `..1' patterns (thanks to Ludovic Courtès)
2010/09/07 - fixing identifier extraction in some `...' and `***' patterns
2009/11/25 - adding `***' tree search patterns
2008/03/20 - fixing bug where (a ...) matched non-lists
2008/03/15 - removing redundant check in vector patterns
2008/03/06 - you can use `...' portably now (thanks to Taylor Campbell)
2007/09/04 - fixing quasiquote patterns
2007/07/21 - allowing ellipsis patterns in non-final list positions
2007/04/10 - fixing potential hygiene issue in match-check-ellipsis (thanks to Taylor Campbell)
2007/04/08 - clean up, commenting
2006/12/24 - bugfixes
2006/12/01 - non-linear patterns, shared variables in OR, get!/set!