Skip to content

Instantly share code, notes, and snippets.

@eraserhd
Created December 16, 2019 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eraserhd/6869f014414ab605efeb4a47410ca214 to your computer and use it in GitHub Desktop.
Save eraserhd/6869f014414ab605efeb4a47410ca214 to your computer and use it in GitHub Desktop.
m/find and m/search
twou.centralpark.server.database.migrations-test=> (m/find prod-snapshot {?p {:program/uuid (m/pred some?)} & (m/not {_ {:program-of-study/program (?p)}})} ?p)
17592186059725
twou.centralpark.server.database.migrations-test=> (m/search prod-snapshot {?p {:program/uuid (m/pred some?)} & (m/not {_ {:program-of-study/program (?p)}})} ?p)
()
@noprompt
Copy link

noprompt commented Dec 16, 2019

I think you're trying to say that there should be no other key in the map that has a :program-of-study/program value that matches (?p).

(let [prod-snapshot {17592186059725 {:program/uuid 1}}]
  (m/find prod-snapshot
    {?p {:program/uuid (m/pred some?)}
     & (m/seqable [_ (m/not {:program-of-study/program (?p)})] ...)}
    ?p))
;; => 17592186059725

(let [prod-snapshot '{17592186059725 {:program/uuid 1}
                      17592186059726 {:program-of-study/program (17592186059725)}
                      17592186059727 {:program-of-study/program (17592186059726)}}]
  (m/find prod-snapshot
    {?p {:program/uuid (m/pred some?)}
     & (m/seqable [_ (m/not {:program-of-study/program (?p)})] ...)}
    ?p))
;; => nil

(let [prod-snapshot {17592186059725 {:program/uuid 1}}]
  (m/search prod-snapshot
    {?p {:program/uuid (m/pred some?)}
     & (m/seqable [_ (m/not {:program-of-study/program (?p)})] ...)}
    ?p))
;; => (17592186059725)


(let [prod-snapshot '{17592186059725 {:program/uuid 1}
                      17592186059726 {:program-of-study/program (17592186059725)}
                      17592186059727 {:program-of-study/program (17592186059726)}}]
  (m/search prod-snapshot
    {?p {:program/uuid (m/pred some?)}
     & (m/seqable [_ (m/not {:program-of-study/program (?p)})] ...)}
    ?p))
;; => ()

@eraserhd
Copy link
Author

Minimal prod-snapshot which exhibits the weirdness.

(def prod-snapshot
  '{17592186059725 {:program/uuid                                 (#uuid "a108443a-71ad-4075-a51d-58c79a2065ea")}
    17592186109750 {:program-of-study/program                     (17592186059725)}})

@eraserhd
Copy link
Author

m/find should return nil here, best as I can understand:

dev=> (m/find prod-snapshot {?p {:program/uuid (m/pred some?)} & (m/not {_ {:program-of-study/program (?p)}})} ?p)
17592186059725

The first part matches:

dev=> (m/find prod-snapshot {_ {:program-of-study/program (?p)}} ?p)
17592186059725

The second part does not:

dev=> (m/find prod-snapshot (m/not {_ {:program-of-study/program (?p)}}) :ok)
nil

The value available inside & is...

dev=> (m/find prod-snapshot {?p {:program/uuid (m/pred some?)} & ?rest} ?rest)
{17592186109750 #:program-of-study{:program (17592186059725)}}
dev=> (def rest-of-map *1)
#'dev/rest-of-map

The negand, substituting the bound value, matches:

dev=> (m/find rest-of-map {_ {:program-of-study/program (17592186059725)}} :ok)
:ok

It's negation, substituting the bound value, fails to match.

dev=> (m/find rest-of-map (m/not {_ {:program-of-study/program (17592186059725)}}) :ok)
nil
dev=>

So the best answer I can think up that would make the behavior correct is if & isn't required to match under m/find. But that doesn't seem to be true:

dev=> (m/find {} {& (m/guard false)} :ok)
nil
dev=> (m/find {} {& (m/guard true)} :ok)
:ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment