This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-02-22
Channels
- # announcements (10)
- # babashka (40)
- # beginners (192)
- # calva (9)
- # cider (2)
- # clj-kondo (9)
- # clojure (69)
- # clojure-dev (15)
- # clojure-europe (29)
- # clojure-gamedev (6)
- # clojure-italy (2)
- # clojure-nl (41)
- # clojure-spec (49)
- # clojure-uk (11)
- # clojurescript (68)
- # conjure (1)
- # cryogen (20)
- # cursive (37)
- # data-oriented-programming (10)
- # data-science (4)
- # datahike (7)
- # datomic (8)
- # depstar (14)
- # emacs (7)
- # events (2)
- # figwheel-main (1)
- # fulcro (81)
- # honeysql (22)
- # hugsql (5)
- # juxt (3)
- # leiningen (8)
- # lsp (314)
- # malli (20)
- # meander (15)
- # membrane (20)
- # mid-cities-meetup (11)
- # practicalli (2)
- # reagent (2)
- # remote-jobs (2)
- # ring-swagger (1)
- # rum (3)
- # sci (21)
- # shadow-cljs (52)
- # startup-in-a-month (1)
- # testing (9)
- # tools-deps (41)
- # vim (8)
- # xtdb (4)
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.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
(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])
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?)))
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!When you come back to this (no pressure), I'd like to understand better what's happening. Here are the macro expansions:
(let*
[R__59579
(clojure.core/case
workspace/example-2
(:a-pattern)
(clojure.core/list :an-action)
meander.match.runtime.epsilon/FAIL)]
(if (meander.match.runtime.epsilon/fail? R__59579) nil R__59579))
(let*
[R__59582
(clojure.core/case
example-2
(:a-pattern)
(clojure.core/list :an-action)
meander.match.runtime.epsilon/FAIL)]
(if (meander.match.runtime.epsilon/fail? R__59582) nil R__59582))
it seems to me that both of them should work :thinking_face:So haven't had a chance to look into it. But judging from the first error, if you pass us a symbol as the first arg, we consider that the "target". Then as a way to make debugging easier, we often use the target name to derive new variables (using gensym or some other safe way). In this case, it looks like we did that in some local function, but since the symbol is not a simple symbol, that broke in the function definition. I don't see that in your macroexpansion. But definitely see it in the spec error you sent.
Yep, it was exactly as I suspected. https://github.com/noprompt/meander/pull/169
This has been fixed in the new release