Neat! You've removed the need to even define a dispatch-fn.  I'll need to
chew on this for a bit (I'm a little slow :) I'm still working on my attempt
at implementing protocols, but I'm not totally clear on where it will go or
how useful it will be.
Seems like this kind of dispatch and the Datalog project might meet up soon?
Or am I totally wrong?
On Thu, Feb 12, 2009 at 12:02 PM, mikel <mev...@mac.com> wrote:

>
> David Nolen and I were recently discussing CLOS and method dispatch. I
> implemented such a scheme for my own use. This post is an FYI for
> David and anyone else who might be interested in generic functions and
> predicate dispatch.
>
> Here's a transcript of a sample session in which I exercise the
> dispatch cases:
>
> (def $gf (make-generic-function))
>
> (add-gf-method $gf [nil] (fn [x] (str "found value: " (.toString x) "
> of type: " (.toString (class x)))))
>
> (add-gf-method $gf [java.lang.Number] (fn [x] (+ x 1)))
>
> (add-gf-method $gf [java.lang.String] (fn [x] (str "Found string: "
> x)))
>
> (add-gf-method $gf [{:equals 5}] (fn [x] (str "Found 5!")))
>
> (add-gf-method $gf [{:model {:name nil}}] (fn [x] (str "Found a thing
> whose name is " (:name x))))
>
> (add-gf-method $gf [java.lang.Number java.lang.Number] (fn [x y] (+ x
> y)))
>
> (add-gf-method $gf [java.lang.String java.lang.String] (fn [x y] (str
> x " " y)))
>
> (add-gf-method $gf [java.lang.String java.lang.Integer] (fn [s i]
> (apply str (take i (cycle [s])))))
>
> (add-gf-method $gf [{:test (fn [x] (= x "swordfish"))}] (fn [s] (str
> "You said the secret word, you win a hundred dollars!")))
>
> user> ($gf "hello" "world")
> "hello world"
> user> ($gf 2 3)
> 5
> user> ($gf {:name "Barney"})
> "Found a thing whose name is Barney"
> user> ($gf 5)
> "Found 5!"
> user> ($gf "bananas")
> "Found string: bananas"
> user> ($gf 100)
> 101
> user> ($gf 'some-symbol)
> "found value: some-symbol of type: class clojure.lang.Symbol"
> user> ($gf "foo" 5)
> "foofoofoofoofoo"
> user> ($gf "swordfish")
> "You said the secret word, you win a hundred dollars!"
>
>
> It works well enough to produce that transcript, but is very
> preliminary. I'm sure there are bugs I haven't noticed yet, and no
> doubt it's terribly slow. For one thing, I know it's doing a lot of
> redundant comparisons at the moment.
>
> It's missing a number of amenities and at least one important feature:
> next-method is not yet implemented.
>
> When called, a generic function matches the arguments it received
> against formal parameters in its dispatch table. Matching of a formal
> parameter works like so:
>
> nil: match any value passed in this position
>
> a Java class: match any value that is an instance of the class (or of
> a subclass of it)
>
> a Map of the form: {:model m}: match any value v for which (model? v
> m) returns true
>
> a Map of the form {:equals x}: match any value v for which (= v x)
> returns true
>
> a Map of the form {:test f}: match any value for which (f x) returns
> true
>
>
> Calling  ($gf 2 3) or whatever works because the object in $gf is a
> closure:
>
> (defn make-generic-function [& [dispatch-table]]
>  (let [dt-ref (or dispatch-table (ref {}))]
>    (fn [& args] (apply-generic-function dt-ref args))))
>
> There's a little trickery with sentinel values and metadata to enable
> me to provide an API for adding and removing methods, which are stored
> in the dispatch-table created in make-generic-function. It would be
> nice to make that code a little less clever, but that would require a
> convenient way to create a new kind of callable object; I'd need to be
> able to define what happens when it's applied.
>
> Now we'll see if this thing is useful enough to make it better.
> >
>

--~--~---------~--~----~------------~-------~--~----~
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
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