Welcome! Please see the About page for a little more info on how this works.

0 votes
in core.match by
I'm very new to {{core.match}} and just started playing around.  Doing so, I came up with this example:


(for [x [[1 2 3]
     [1 2 3 4]
     {:a 17, :b 2}
     {:a 23, :b 7}]]
  (match [x]
   [[a b c]]                    [a b c]
   [{:a a, :b 2}]               {:a a}
   [{:a (a :guard odd?), :b b}] {:a a, :b b}
   :else                        :no-match))


This errors with the message ??"IllegalArgumentException Argument must be an integer: :clojure.core.match/not-found clojure.core/even? core.clj:1351)"??.  The problem is that the keyword {{:clojure.core.match/not-found}} is passed to the {{:guard}} function {{odd?}} which passes it to {{even?}}.

I can fix it by ensuring the my guard only gets an integer like so:


(for [x [[1 2]
        [1 2 3]
        [1 2 3 4]
        {:a 17, :b 2}
        {:a 23, :b 7}]]
  (match [x]
   [[a b c]]                               [a b c]
   [{:a a, :b 2}]                          {:a a}
   [{:a (a :guard #(and (integer? %)
                        (odd? %))), :b b}] {:a a, :b b}
   :else                                   :no-match))


But is it really intensional that guards have to deal with {{:clojure.core.match/not-found?}}  In my opinion, in the example above all maps that are matched have integer values, so it seems plausible that I can have a guard that only accepts integers.

2 Answers

0 votes
by

Comment made by: tsdh

You can actually use that {{:clojure.core.match/not-found}} special value to make a kind of perverted map pattern that matches only if it doesn't match like so.

(match [{:a 1}] [{:b (a :guard #(identical? % :clojure.core.match/not-found))}] :yes :else :no) ;=> yes

But I guess (and hope) nobody relies on such a strange behavior.

0 votes
by
...