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

Reply via email to