Skip to content
/ match Public

A Pattern matching macro for (Chez Scheme)

Notifications You must be signed in to change notification settings

absop/match

Repository files navigation

match

A pattern matching macro for (Chez Scheme)

Usage

Patterns

p ::= _
    | ()
    | ,x
    | ,(sat? x)
    | ,(sat?)
    | (tag ,x y ...)    -- record-type
    | (pcar ... . rest)
    | (pcar . pcdr)
    | symbol
    | datum

Match any things

  1. The wildcard _ can be used to match anything.
  2. The pattern ,x matches anything as well, and binds the corresponding value to x.

Match things that satisfied a condition

  1. ,(sat?) matches a value that satisfied the condition sat?.
  2. ,(sat? x) matches a value that satisfied the condition sat? and binds it to x.

Match literals

symbol & datum are other patterns, and will be matched as literals.

Match a list of things with ellipsis

  1. matching a list

    code

    (match '(x y z 1 2 3 . end)
      [(,(symbol? syms) ... ,rest ... . end)
       (printf "syms: ~a\n" syms)
       (printf "rest: ~a\n" rest)])

    output

    syms: (x y z)
    rest: (1 2 3)
    
  2. matching list of lists

    code

    (match '(let-values
              ([(x y z) (values 1 2 3)] [(a b c) (values 'a 'b 'c)])
              (list a b c x y z))
      [(let-values ([(,(symbol? vars) ...) ,exps] ...) ,body ...)
       (printf "~a\n" `(let-values ,vars ,exps ,body))])

    output

    (let-values ((x y z) (a b c)) ((values 1 2 3) (values 'a 'b 'c))
      ((list a b c x y z)))
    

    code

    (match '(1 2 3 1 2 3 (1 2 3))
      [(,x ... ,y ... (,z ...))
       (printf "x=~a, y=~a, z=~a\n" x y z)])

    output

    x=(1 2 3 1 2 3), y=(), z=(1 2 3)
    

Use Same binding names to match same structures

  1. Same values

    code

    (match '(1 1 (1))
      [(,x ,x (,x))
       (printf "x=~a\n" x)])

    output

    x=1
    
  2. Same lists

    code

    (match '(1 2 3 (1 2 3))
      [(,x ... (,x ...))
       (printf "x=~a\n" x)])

    output

    x=(1 2 3)
    

    code

    (match '(1 2 3 1 2 3 (1 2 3))
      [(,x ... ,x ... (,x ...))
       (printf "x=~a\n" x)])

    output

    x=(1 2 3)
    

Match record type

Suppose the following record-type is provided.

(define-record-type point (fields x y))
  1. code

    (match (make-point 1 2)
      [(point 1 2) #t])

    output

    #t
    
  2. code

    (match (make-point 1 2)
      [(point ,x ,y) (+ x y)])

    or

    (match (make-point 1 2)
      [(point ,y ,x) (+ x y)])

    output

    3
    
  3. code

    (match (make-point 1 2)
      [(point ,x 2) x])

    or

    (match (make-point 1 2)
      [(point ,x) x])

    or

    (match (make-point 1 2)
      [(point ,x _) x])

    output

    1
    
  4. code

    (match (make-point 1 2)
      [(point 2 ,x) x])

    output

    Exception in match: duplicated fields found in the record pattern (point 2 ,x)
    

Type (debug) to enter the debugger.


5. code
```scheme
(match (make-point 1 2)
  [(point ,z ,y) y])

output

Exception in match: z is not a field of the record type point
Type (debug) to enter the debugger.

More details

To learn more about the usage, please read the following examples under this directory:

  1. church-compile.ss
  2. interp-with-match.ss.

To see what the match statement will expand into, you can use the expand function to expand the macro.

(parameterize ([print-gensym 'pretty/suffix])
  (pretty-print
    (expand
      '(match exp ...))))

The file interp-with-match.expanded.ss in this directory is generated by the file expand-test.ss, with the file interp-with-match.ss as the input.

To learn more about the implementation, please read the source file match.ss directly.

Currently, nested quasiquote patterns is not well supported.

About

A Pattern matching macro for (Chez Scheme)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages