Pattern matching

Scheme Macrology: a generalized and guarded matcher

This post describes and defines the match/guarded pattern matcher, which is a generalization of Oleg Kiselyov’s pmatch.

Tests

test/base: pass

(define (test/base _)
  (⊦= 'empty (match/guarded '() (() 'empty)))
  (⊦= 'empty (match/guarded #() (() 'empty)))
  (⊦= '() (match/guarded '() (,r r)))
  (⊦= #() (match/guarded #() (,r r)))
  (⊦= 'p (match/guarded '(p) ((,r) r)))
  (⊦= #t (match/guarded #(p) ((p) #t)))
  (⊦= 'p (match/guarded #(p) ((,r) r)))
  (⊦= 3 (match/guarded #(3 2) ((,r 2) r)))
  (⊦= '(3 #(2)) (match/guarded #(3 2) ((,r unquote s) (list r s))))
  (⊦⧳ ((exn)) (match/guarded #(3 2) ((,r 2 ,t) r)))
  (⊦= 3 (match/guarded #(3 2) ((,r ,e) r)))
  (⊦= 3 (match/guarded (make-record-instance 'hello 3 2) ((hello ,r ,e) r))))
((eta 0.002) (memory #(12582912 3067880 1048576)) (stdout "") (stderr ""))

test/h: pass

(define (test/h _)
  (define h
    (lambda (x y)
      (match/guarded
        `(,x unquote y)
        "h function, example"
        ((,a unquote b) (guard (number? a) (number? b)) (* a b))
        ((,a ,b ,c) (guard (number? a) (number? b) (number? c)) (+ a b c)))))
  (⊦= '(12 8) (list (h 3 4) (apply h '(1 (3 4))))))
((eta 0.001) (memory #(12582912 3068656 1048576)) (stdout "") (stderr ""))

test/h-wrong: pass

(define (test/h-wrong _)
  (define h
    (lambda (x y)
      (match/guarded
        `(,x unquote y)
        "h function, example"
        ((,a unquote b) (guard (number? a) (number? b)) (* a b))
        ((,a unquote b) (+ a b))
        ((,a ,b ,c) (guard (number? a) (number? b) (number? c)) (+ a b c)))))
  (⊦⧳ ((exn)) (list (h 3 4) (apply h '(1 (3 4))))))
((eta 0.0) (memory #(12582912 3073520 1048576)) (stdout "") (stderr ""))

See also