[racket] Pattern matching define macro
I'm porting more Haskell code to Racket as a learning exercise. When I got to this line:
isPos (r,c) = elem r [0..4] && elem c [0..r]
I first wrote this:
(define (is-pos r c) (and (member r (lgen 0 4))
(member c (lgen 0 r))))
where lgen is:
(define (lgen m n) (build-list (+ 1 (- n m)) (λ (x) (+ x m))))
I think (lgen 0 r) is a reasonable alternative to [0..r], and the minor additional length of the Racket version is fine.
I then decided that I may prefer to a list of row/col instead of individual args and bumped into a need for destructuring a list, so I wrote this macro:
(define-syntax defpat
(syntax-rules ()
[(_ (fn pat) b1 b2 ...)
(define fn (match-lambda [pat b1 b2 ...]))]))
which allows:
(defpat (is-pos (list r c)) (and (member r (lgen 0 4))
(member c (lgen 0 r))))
The fact that this is such a common operation and I couldn't find anything built-in makes me think that I may be missing something. Is this a reasonable solution? Are there better alternatives?
I suppose a better name might be in order since it's not matching one of several patterns; in this case, it's really just for destructuring a list more concisely.
I'm still blown away by how easy it was to mold Racket closer to what I wanted. I've just barely begun learning macros, but syntax-rules made this pretty easy.
I think the only thing that sticks out is the "list" function, but that seems like a reasonable sacrifice given the flexibility it allows for in more complicated patterns.
Thanks,
Brian
--
Brian Adkins
Lojic Technologies, LLC
http://lojic.com/