core.match

Do :guard predicates really need to handle :clojure.core.match/not-found?

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    Clojure 1.7.0 beta4, core.match 0.3.0-alpha3

Description

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.

Activity

Hide
Tassilo Horn added a comment -

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.

Show
Tassilo Horn added a comment - 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.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated: