Hi all, just reading through the meander docs, and wondering if anyone could shed light on what the difference is between the scan
and [ ...]
formulations? For example:
{:user
{:name ?name
:favorite-foods (m/scan {:name ?food})}}
{:user
{:name ?name
:favorite-foods [{:name !food} ...]}}
(m/scan p1 ,,, pn)
is similar to
[_ ... p1 ,,, pn & _]
or
(_ ... p1 ,,, pn & _)
but operates on seqable?
things in general.(m/match #{{:id 1} {:id 2}} #{{:id 1}} :yes)
works, but:
(m/match #{{:id 1} {:id 2}} #{{:id ?id}} :yes)
says that Set patterns may not contain variables
. Does that mean that I can't check that a pattern is a subset of my data if it has logical variables, or is there a better way of expressing something like this?Match requires things to be unambigious. But that isnβt the case here. So you can use m/search
to get all the answers, or m/find
to get the first.
(m/search #{{:id 1} {:id 2}}
#{{:id ?id}}
[?id :yes])
;; =>
([2 :yes] [1 :yes])
To explain the difference a bit more concretely, scan lets there be gaps in the data, where as ...
requires all elements to make the pattern. You can see that in the difference between these two.
(m/search [1 2 3 4 5 6]
(m/scan (m/pred even? ?xs))
?xs)
;; => [2 4 6]
(m/find [1 2 3 4 5 6]
[(m/pred even? !xs) ...]
!xs)
;; => nil
thanks for the answer @jimmy, that's exactly what I needed! Amazing library!
I'm observing a weird behaviour that I think could be a bug. I'm in a cljs file: if I do
(m/search example-2 a-pattern an-action)
where example-2 is an actual binding in my file, all is good. But if I try to import the same binding from another file, writing:
(m/search workspace/example-2 a-pattern an-action)
then i get a spec error:
Syntax error macroexpanding cljs.core/fn.
Call to cljs.core/fn did not conform to spec.
-- Spec failed --------------------
([workspace/example-2_T__] ...)
^^^^^^^^^^^^^^^^^^^^^^^
has extra input
or
should satisfy
vector?
-- Relevant specs -------
:shadow.cljs.devtools.cljs-specs/param-list:
(clojure.spec.alpha/and
clojure.core/vector?
(clojure.spec.alpha/cat
:params
(clojure.spec.alpha/* :shadow.cljs.devtools.cljs-specs/binding-form)
:var-params
(clojure.spec.alpha/?
(clojure.spec.alpha/cat
:ampersand
#{'&}
:var-form
:shadow.cljs.devtools.cljs-specs/binding-form))))
:shadow.cljs.devtools.cljs-specs/params+body:
(clojure.spec.alpha/cat
:params
:shadow.cljs.devtools.cljs-specs/param-list
:body
(clojure.spec.alpha/alt
:prepost+body
(clojure.spec.alpha/cat
:prepost
clojure.core/map?
:body
(clojure.spec.alpha/+ clojure.core/any?))
:body
(clojure.spec.alpha/* clojure.core/any?)))
This has been fixed in the new release
Sounds like a bug. If you let bins workspace/example-2 to a local variable does it work? Can't look at this right now. But will try to recreate tonight.
yes, either a variable in the same file or a variable in a let binding works:
(let [example-2 ...]
(m/search example-2 a-pattern an-action))
Thank you!Cool should be an easy fix.
and of course this works too:
(let [example-2 workspace/example-2] ...)