I'm not sure I understand. My model suggests that m/find = first . m/search
(the docstring for m/find says as much, AFICT), so seeing m/find return a value when m/search doesn't seem right.
Ok, I updated the gist with the minimal data and some results poking at it. I still can't model what is happening, though.
I think it is a bug. Looking at some codegen now and I think there is some bad code generated in search. Trying to track it down a bit more
@noprompt and I are agreed that it is a bug. Here’s my minimal reproducible case.
(let [prod-snapshot
{1 2
2 1
3 5
5 3}]
(m/search prod-snapshot
{?p _
& (m/not {_ ?p})}
?p))
=>
()
There is some bad codegen that is making search stop short when it should continue searching.I expect that m/search to be empty. Are you saying there's a bug in the m/find version of that?
I'm not entirely sure my expectations are right, but m/find for that returns 5
, and I expect nil, while m/search for that I would expect to be ().
No, the search there should not be empty. I intentionally set it up so that should return back all the keys. Consider 1. Remove [1 2] from the map. We are left with [[2 1] [3 5] [5 3]]. Now we are saying find me some case where 1 is not the value. Well, there is such a case. In fact, there are two. [3 5] [5 3]
"find me some case where 1 is not the value" is {_ (m/not ?p)}
, though, right?
Yes
But also (m/not {_ ?p})
hmmm
I'm skeptical, but not sure I can prove it.
(m/search {1 2
2 3}
(m/not {_ 2})
:yep)
=>
:yep
I get nil
One second need to restart my repl
Let’s start here.
(m/find {1 2 2 3}
{_ 2}
:yep)
=> :yep
got same, and me brain agrees.
Maps in meander work a lot like sets.
(m/find #{1 2 3}
#{1}
:yep)
=> :yep
got same, and me brain still agrees :)
So in that case we are saying that there exists some value that is 2. We are not saying all values are 2.
right
Okay, hold on let me formulate my thoughts
ok
Okay, so what we are saying with (m/not {_ 2})
is do I have a map such that {_ 2}
will not match it. So what maps are those? Maps without any values that are 2.
Or to put it another way a map that does not have a 2 as a value
I’ve got to head to bed. But hopefully that makes sense. Joel is working on fixing the issue now.
I think this statement is how I've been interpreting it, and why I think m/search should return () above.
g'night. past my bedtime too :D
I realized that I said it wrong. But no time to say it right. I will revisit with an explanation tomorrow.
Negation is hard
The best way to think about it is in terms of submaps. Is there sub map that fails to match? Yes there is. So it matches.
This implies there are patterns P for which (m/and P (m/not P))
match.
Alrighty. Thanks to some help from Jimmy, I think I should have a patch for this