Am I misunderstanding the usage of m/or? I thought this should work:
(meander/match
;; input
{:foo nil}
;; pattern
{:foo (m/or nil {:bar ?bar})}
;; expression
:aaa)
but it gives me non exhaustive pattern match while i expected to return :aaaNot a meander expert at all, but I’ve used it in the past.
I remember that there is a difference between plain ?x and memory variable !x,
so the following works ca. as I would expect:
(m/match {:foo [1 2 3]}
{:foo (m/or nil [!x ...])}
!x)
;; => [1 2 3]
(m/match {:foo nil}
{:foo (m/or nil [!x ...])}
!x)
;; => []
On the other hand, your example throws. It seems that it expects to ‘see’ the same symbols bound in both (all) branches of m/or—you can ‘hack’ it like so (probably shouldn’t, this is just for demonstration):
(m/match {:foo nil}
{:foo (m/or (m/let [?s nil] ?s) ?s)}
{:val-of-s ?s})
But what is the underlying reason I don’t remember, if I ever I knew it at all ;Papparently it is idiomatic to use (s/and ,,,) instead of how I used (m/let ,,,) above, see the “maybe” pattern: https://github.com/noprompt/meander/blob/epsilon/doc/cookbook.md#the-maybe-pattern,
well, it seems that even the cookbook example doesn't work:
(meander/match
;; input
{:foo nil}
;; pattern
{:foo (m/or (m/and nil ?bar)
{:bar ?bar})}
;; expression
:aaa))
=> non exhaustive pattern matchthis seems to work for me
;; meander/epsilon {:mvn/version "0.0.650"}
(require '[meander.epsilon :as m])
(m/match
{:foo nil}
{:foo (m/or (m/and nil ?bar)
{:bar ?bar})}
:aaa)
;; => :aaa
in your snippet you have meander/match but m/or
instead it should be the following if you want to alias to meander
(require '[meander.epsilon :as meander])
(meander/match
{:foo nil}
{:foo (meander/or (meander/and nil ?bar)
{:bar ?bar})}
:aaa) I do remember getting an error (or warning) when using meander/or inside the match macro, that didn't happen with m/or inside the macro
Well, for some reason, requiring meander :as meander and doing meander/match instead of m/match messes up the result
I really don't know why
So it seems you are right. Here are some POCs for future searchers: not working:
clj -Sdeps '{:deps {meander/epsilon {:mvn/version "0.0.650"}}}' -e '(require '"'"'[meander.epsilon :as meander]) (meander/match {:foo nil} {:foo (m/or (m/and nil ?bar) {:bar ?bar})} :aaa)'
WARNING: Implicit use of clojure.main with options is deprecated, use -M -e (require '[meander.epsilon :as meander]) (meander/match {:foo nil} {:foo (m/or (m/and nil ?bar) {:bar ?bar})} :aaa)
Reflection warning, meander/util/epsilon.cljc:758:24 - reference to field val can't be resolved.
Execution error (ExceptionInfo) at user/eval6276 (REPL:1).
non exhaustive pattern match
Full report at:
/tmp/clojure-9301841438482740125.edn
working:
clj -Sdeps '{:deps {meander/epsilon {:mvn/version "0.0.650"}}}' -e '(require '"'"'[meander.epsilon :as meander]) (meander/match {:foo nil} {:foo (meander/or (meander/and nil ?bar) {:bar ?bar})} :aaa)'
WARNING: Implicit use of clojure.main with options is deprecated, use -M -e (require '[meander.epsilon :as meander]) (meander/match {:foo nil} {:foo (meander/or (meander/and nil ?bar) {:bar ?bar})} :aaa)
Reflection warning, meander/util/epsilon.cljc:758:24 - reference to field val can't be resolved.
:aaaIn the second form a clj-kondo warning about unresolved var meander/or and meander/and pops up that is a bit misleading (that doesn't appear in the first form)