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