Design question: I made a new branch of the code where you extend the Is-A protocol on the parent instead of the child. My reasoning is that when you define multimethods, the dispatch value is the parent of the is-a relation. Since you control these values, and have less control over the child (~= the user's input to your multimethod), it makes more sense to extend the protocol on the parent. Does that seem reasonable?
As a result, you can do some interesting things now. Here are some examples from the test suite: (is (true? (is-a? "" string?))) (is (false? (is-a? [] seq))) ; nil -> false (is (true? (is-a? [1] seq))) (testing "even anonymous fns work." (is (true? (is-a? [:kw "str" 1] ;; first number is a 1? #(if-let [x (first (filter number? %))] (= x 1))))) (is (false? (is-a? [:kw 2 "str" 1] ;; first number is a 1? #(if-let [x (first (filter number? %))] (= x 1)))))))) (is (true? (is-a? {:a 1 :b "foo" :c Double :d "exact" :e :other} {:a number? :b #"foo.*" :c Number :d "exact"}))) In case you weren't paying close attention, you can dispatch on any predicate, on a regex matching an input string, on a map subsuming the input map, any rule that core/isa? uses, and / or... lots of other things you want to do, but I can't think of. It's starting to look like a pattern matcher. Maybe it's starting to look like something else to you, too, but let's keep it friendly :) Downsides: - You can extend a multimethod you don't control like this, but you'd better pray you don't introduce ambiguities. By the way, with this much flexibility, you *will* introduce ambiguities. core/isa?, derive, etc. are designed to detect ambiguity and have you resolve it by hand. Predicate dispatch will, among its other lovely qualities, detect (most?) ambiguous, implied, or impossible dispatch predicates. - Slow. If you're dispatching to a fn that runs for > 10ms, it's not a huge problem. But, yeah, it's a lot slower than any other kind of dispatch. But if you're doing dispatch this complicated, the speedy alternative is giant nested cond and case statements. As always comments, etc. welcome. --Leif On Wednesday, July 11, 2012 2:16:30 AM UTC-4, Leif wrote: > > Hi, everybody. I reimplemented the function isa? in terms of a protocol > Is-A. > > The reason why you would want to do that is in the README at > https://github.com/leifp/clj-isa-protocol > > tl;dr: One of the reasons why people are excited about predicate dispatch > is the irritation caused by the dispatch function of a multimethod being > closed. You have to decide up front what information the dispatch fn is > going to pull out of your arguments. Changing it afterward is a pain. > > Since the dispatch uses 'isa?' internally, if that function is extensible, > then multimethod dispatch becomes, to a certain extent, open. See the > README. > > Comments, critique, code, and questions welcome. > > Cheers, > Leif > > P.S. As an aside to people that like weird, obscure programming > languages, the rough idea of how is-a? should work for maps was inspired by > (but very much simpler than) the functional logic language LIFE [ > http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.3175 ] > -- 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