David Pollak
added a comment - 29/May/13 10:38 PM Thanks David. I was thinking about putting a "is this really a wildcard" flag on Wildcard and set it to false for Wildcards in MapPattern.
Anyway... if you want me to keep working on the issue, I'll be glad to. If my clumsy code and clumsy approach doesn't help... I'm down for sitting on the sidelines and watching you do the work.

The issue is a bit trickier than it seems. core.match is written in a way such that we always try to share tests across patterns as much as possible. For example consider what happens with map patterns:

(match [x]
[{:a _ :b 1}] ...
[{:b _ :c 2}] ...)

In order to do optimal test sharing we expand the above into the following more or less (which is wrong):

:a :b :c
[_ 1 _]
[_ _ 2]

The problem here is that only the last element in the first row and the first element of the second row are true wildcards. Currently as you discovered the analysis doesn't consider the fact that the other wildcards really must be tested. So really we want something like the following:

:a :b :c
[V(_) 1 _]
[_ V(_) 2]

Here you can see we wrap the wildcard in a new pattern type - MapValuePattern. This will prevent the bad analysis.

I hope this makes sense - I've started implementing this and I don't think it will take me too long.

Just to make it a bit more clear imagine the following:

(match [x]
[{:a _ :b _}] ...
[{:b _ :c _}] ...)

:a :b :c
[V(_) V(_) _ ]
[_ V(_) V(_)]

The wrapping now prevents the first row from being considered a row of wildcards.

David Nolen
added a comment - 30/May/13 12:35 AM - edited The issue is a bit trickier than it seems. core.match is written in a way such that we always try to share tests across patterns as much as possible. For example consider what happens with map patterns:

(match [x]
[{:a _ :b 1}] ...
[{:b _ :c 2}] ...)

In order to do optimal test sharing we expand the above into the following more or less (which is wrong):

:a :b :c
[_ 1 _]
[_ _ 2]

The problem here is that only the last element in the first row and the first element of the second row are true wildcards. Currently as you discovered the analysis doesn't consider the fact that the other wildcards really must be tested. So really we want something like the following:

:a :b :c
[V(_) 1 _]
[_ V(_) 2]

Here you can see we wrap the wildcard in a new pattern type - MapValuePattern. This will prevent the bad analysis.
I hope this makes sense - I've started implementing this and I don't think it will take me too long.
Just to make it a bit more clear imagine the following:

(match [x]
[{:a _ :b _}] ...
[{:b _ :c _}] ...)

:a :b :c
[V(_) V(_) _ ]
[_ V(_) V(_)]

The wrapping now prevents the first row from being considered a row of wildcards.