Putting that kind of logic in IMatchLookup doesn't make much sense to me: I'm not sure about the following syntax, but something like this could be done w/o interfering with IMatchLookup.
(match [obj] [({:mice 4} :type cat)] ... [({:cats 4} :type dog)] ... [({:cats 4} :type :not [cat dog]] ...) This can be done by creating something like TypePattern which would understand these various cases. However it does sound like you want predicate dispatch. Whatever syntax is decided upon needs to work for the open dispatch case as well as it does for the matching case. Predicate dispatch is on the roadmap but still some ways off. Definitely open to discussion. David On Tue, Jan 3, 2012 at 2:56 PM, Tassilo Horn <tass...@member.fsf.org> wrote: > David Nolen <dnolen.li...@gmail.com> writes: > > Hi David, > > >> In my patterns, I want to have a :+type key with a value that's > >> basically an interface name given as a symbol. The pattern should > >> match, if the class of the object implements that interface (or an > >> extended interface thereof) directly or indirectly. So that would be > >> my ideal user interface: > >> > >> --8<---------------cut here---------------start------------->8--- > >> (match [obj] > >> [{:+type 'Cat :mice 4}] :1 > >> [{:+type 'Dog :cats 3}] :2 > >> [{:+type 'Mammal}] :3 > >> :else :nope) > >> --8<---------------cut here---------------end--------------->8--- > > > > This is a known missing feature and there's a couple of open questions > > as far as how to best implement this. It should probably support Java > > classes, Java interfaces, types, records, protocols and high > > performance hinted access to fields. > > I'm not sure, if you've stopped reading there, so let me make my issue > clear. I'm *not* especially interested in some new feature for > efficiently matching on types, although that wouldn't be bad either. > > What I'd like to have was a way to influence when a certain key with a > certain value matches for my IMatchLookup extending custom type. So if > IMatchLookup/val-at would be allowed to return a predicate that given > the value from the pattern tests if the match succeeds. > > Here's a patch against the master version of core.match that makes my > Cat, Dog, Mamal example work, but it's only meant for illustration. > > --8<---------------cut here---------------start------------->8--- > --- a/src/main/clojure/clojure/core/match.clj > +++ b/src/main/clojure/clojure/core/match.clj > @@ -864,8 +864,12 @@ > (to-source* [this ocr] > (cond > (= l ()) `(empty? ~ocr) > - (and (symbol? l) (not (-> l meta :local))) `(= ~ocr '~l) > - :else `(= ~ocr ~l))) > + (and (symbol? l) (not (-> l meta :local))) `(if (fn? ~ocr) > + (~ocr '~l) > + (= ~ocr '~l)) > + :else `(if (fn? ~ocr) > + (~ocr ~l) > + (= ~ocr ~l)))) > Object > (toString [_] > (if (nil? l) > --8<---------------cut here---------------end--------------->8--- > > I changed the LiteralPattern to-source* function to include a check if > ocr is a function. In that case, I apply it to the value l, else I > stick to the usulal (= ocr l) comparison. With that change, I can make > my val-at implementations return predicates like so: > > --8<---------------cut here---------------start------------->8--- > (extend-protocol IMatchLookup > ;; ... > de.uni_koblenz.jgralab.Vertex > (val-at [this k not-found] > (case k > :+type (fn [x] > ((core/type-matcher (graph this) x) this)) > ;; ... > (match-attribute this k not-found)))))) > --8<---------------cut here---------------end--------------->8--- > > That makes my Cat, Dog, Mammal example work fine. But of course, it > works only for literal patterns, whereas my `type-matcher' function > above also accepts type specifications like [:and !Cat !Dog!] meaning > the object's type must be not a Cat and not exactly a Dog (but some Dog > subtype would be fine, and of course Birds, Fish, etc.). > > So how would one tackle that issue in a general way? I guess, we'd need > some new pattern type, PredicatePattern, right? What might be a good > syntax for it? If you beat me to it, I'd give it a shot. > > Bye, > Tassilo > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en