Re: Generic functions: things, models, and protocols revisited

2009-02-12 Thread David Nolen
>
>
> > Seems like this kind of dispatch and the Datalog project might meet up
> soon?
> > Or am I totally wrong?
>
> I have given it zero thought.


Perhaps interesting to pursue? Rich had brought it up in conversations about
predicate dispatch. Could greatly help from the performance side of things?

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



Re: Generic functions: things, models, and protocols revisited

2009-02-12 Thread mikel



On Feb 12, 1:27 pm, David Nolen  wrote:
> Neat! You've removed the need to even define a dispatch-fn.

Maybe; maybe not. The built-in dispatch mechanism uses a selection
scheme that applies a sequence of increasingly restrictive, but also
increasingly costly, tests; basically, the tests in order are: (1)
identity; (2) isa? (3) model? (is this value a map and are all its
keys members of one or more test maps) (4) = (5) an arbitrary user-
supplied test. A fuller implementation should probably provide the
option of replacing that dispatch algorithm with one of your own
choosing, probably as an option to make-generic-function.

> Seems like this kind of dispatch and the Datalog project might meet up soon?
> Or am I totally wrong?

I have given it zero thought.


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



Re: Generic functions: things, models, and protocols revisited

2009-02-12 Thread David Nolen
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  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
-~--~~~~--~~--~--~---



Generic functions: things, models, and protocols revisited

2009-02-12 Thread mikel

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