[plt-scheme] match expander weirdness
Hi,
I am experiencing a weird problem with (renamed) match expanders. The
creatures in reference deconstruct structs that come from different
modules, but have the same name in their respective modules.
Example:
(module sa mzscheme
(require (lib "plt-match.ss"))
(define-struct foo (x y z) #f)
(define-match-expander Foo
#:plt-match
(lambda (stx)
(syntax-case stx ()
((_Foo field ...)
#'(? foo? (app struct->vector (vector _ field ...))))))
#:expression
(lambda (stx)
(syntax-case stx ()
((_Foo field ...)
#'(make-foo field ...)))))
(define-match-expander Foo2
#:plt-match
(lambda (stx)
(syntax-case stx ()
((_Foo2 field ...)
#'(struct foo (field ...))))))
(provide (all-defined))
)
Now, let's define a second module, that has a foo with two fields instead
of three:
(module sb mzscheme
(require (lib "plt-match.ss"))
(define-struct foo (x y) #f)
(define-match-expander Foo
#:plt-match
(lambda (stx)
(syntax-case stx ()
((_Foo field ...)
#'(? foo? (app struct->vector (vector _ field ...))))))
#:expression
(lambda (stx)
(syntax-case stx ()
((_Foo field ...)
#'(make-foo field ...)))))
(define-match-expander Foo2
#:plt-match
(lambda (stx)
(syntax-case stx ()
((_Foo2 field ...)
#'(struct foo (field ...))))))
(provide (all-defined))
)
and then:
> (version)
"369.8"
> (require (lib "plt-match.ss"))
> (require (rename "sa.ss" a:Foo Foo))
> (require (rename "sb.ss" b:Foo Foo))
> (match (a:Foo 1 2 3) ((b:Foo _ _) 'b) ((a:Foo _ _ _) 'a))
match: no matching clause for #4(struct:foo 1 2 3)
> (match (a:Foo 1 2 3) ((a:Foo _ _ _) 'a) ((b:Foo _ _) 'b))
a
> (match (b:Foo 1 2) ((a:Foo _ _ _) 'a) ((b:Foo _ _) 'b))
match: no matching clause for #3(struct:foo 1 2)
> (match (b:Foo 1 2) ((b:Foo _ _) 'b) ((a:Foo _ _ _) 'a))
b
> (require (rename "sa.ss" a:Foo2 Foo2))
> (require (rename "sb.ss" b:Foo2 Foo2))
> (match (a:Foo 1 2 3) ((a:Foo2 _ _ _) 'a) ((b:Foo2 _ _) 'b))
Warning: unreachable match clause ((b:Foo2 _ _) (quote b)) in (match
(a:Foo 1 2 3) ((a:Foo2 _ _ _) (quote a)) ((b:Foo2 _ _) (quote b)))
a
> (match (b:Foo 1 2) ((a:Foo2 _ _ _) 'a) ((b:Foo2 _ _) 'b))
Warning: unreachable match clause ((b:Foo2 _ _) (quote b)) in (match
(b:Foo 1 2) ((a:Foo2 _ _ _) (quote a)) ((b:Foo2 _ _) (quote b)))
match: no matching clause for #3(struct:foo 1 2)
It seems that in each case the pattern compiler somehow decides that
the second pattern is unreachable (silently in the struct->vector
decomposition)...
-- vyzo