New Object Model Demo

Hello Everyone,
I have posted an alpha version of a new Object System Library that I'm writing in Scheme (currently using MzScheme only). It combines the Prototypes with Multiple Dispatch object model from the Slate programming language (as described in this document) with Method Combination from CLOS (as described in section ten of this document), to create an object system which I believe to be novel (having found no evidence to the contrary). It is available from the project page or directly from the download site.

I have not had much time to work on it, so it currently only has some debug behavioral print-outs, but if anyone's interested, I could clean up the code into a portable library, and perhaps document it a bit more.

Feedback is appreciated,
Ryan Kaulakis

Note: This is an update from this earlier post.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Not enough info

That looks interesting but I could not find enough information to understand what you are offering. There is no documentation on the project site and the linked documents are not free access.

What can I do with your object system library?

slate homepage, with the papers i think

Ah

Yes, there is almost no documentation yet on how the system works, but that's due to time being in such short supply for me at the moment.

The object system allows you to do CLOS style method combination over prototypes. Here's some examples (note that it handles diamond and circular inheritance correctly):
(pardon the formatting)


;;make a bunch of objects and play with them
(define obj1 (make-obj '())) ;;a standard object
(define obj2 (make-obj (list obj1))) ;;a child
(define obj-circle (let ((temp (make-obj '())))
(hash-table-set! temp 'parents (list temp))
temp)) ;;an object which is it's own parent (why would anyone ever need that?)
(define obj3 (make-obj (list obj1))) ;;a sibling
(define obj-diamond (make-obj (list obj2 obj3))) ;;diamond inheritance pattern

;;now give everyone ID's
(%set! obj1 'id "obj1")
(%set! obj2 'id "obj2")
(%set! obj3 'id "obj3")
(%set! obj-circle 'id "obj-circle")
(%set! obj-diamond 'id "obj-diamond")

;;make a CLOS style generic function, that works on prototypes
;;evaluation rules come from Slate and CLOS
(def-generic 'pretty-print-pair 'Item-A 'Item-B)
(def-method ('pretty-print-pair 'standard ((obj1 foo) (obj1 bar)))
(display "Both are of type obj1\n")
(display "Contents are: (")
(display (%get foo 'id))
(display ",")
(display (%get bar 'id))
(display ")\n"))
(def-method ('pretty-print-pair 'before ((obj1 x) (obj1 y)))
(display "\n---Prep work---\n"))
(def-method ('pretty-print-pair 'after ((obj1 x) (obj1 y)))
(display "\n---Cleanup work---\n"))
(def-method ('pretty-print-pair 'standard ((obj2 x) (obj1 y)))
(display "The First argument is type obj2, let's keep going...\n")
(call-next-method))
(def-method ('pretty-print-pair 'standard ((obj1 x) (obj2 y)))
(display "The Second argument is type obj2, let's keep going...\n")
(call-next-method))
(def-method ('pretty-print-pair 'standard ((obj-diamond a) (obj-diamond b)))
(display "Both are type obj-diamond\n")
(display "They're special, let's stop\n"))

;;running
(pretty-print-pair obj1 obj2)
;;gives you

---Prep work---
The Second argument is type obj2, let's keep going...
Both are of type obj1
Contents are: (obj1,obj2)

---Cleanup work---

;;running
(pretty-print-pair obj2 obj2)
;;gives you

---Prep work---
The First argument is type obj2, let's keep going...
The Second argument is type obj2, let's keep going...
Both are of type obj1
Contents are: (obj2,obj2)

---Cleanup work---

;;runnning
(pretty-print-pair obj-diamond obj2)
;;gives you

---Prep work---
The First argument is type obj2, let's keep going...
The Second argument is type obj2, let's keep going...
Both are of type obj1
Contents are: (obj-diamond,obj2)

---Cleanup work---

;;running
(pretty-print-pair obj-diamond obj-diamond)
;;gives you

---Prep work---
Both are type obj-diamond
They're special, let's stop

---Cleanup work---

Nice example

Thank you....

How is Slate multi-dispatch different from CLOS multimethods?

PMD

Slate's multi-dispatch (and inheritance) works on the level of individual objects without regard to classes, whereas in CLOS even though there is instance-specific dispatch, the class is the central theme. Also, Slate's model is oriented towards bottom-up programming as contrasted with CLOS' use of generics to fit in with non-polymorphic Common Lisp. That is, implementation-wise, the objects alone are enough to carry a multimethod, instead of requiring a generic function to index them.

Well...

The short answer is that Slate does multi-dispatch over prototypes, while CLOS does it over classes. That part isn't particularly interesting, but the related issue of "how do I order calls for method-combinations" is quite neat.

In this library, the algorithm is:

1) Given a list of objects, check to see if there is a specific annotation which matches every item in the list. This is the most specific annotation

2) Then, moving lexically from left to right, find all applicable annotations which match the parent of each object followed by the rest of the objects. (which are not already noted)

3) Repeat this for each additional step away from the most specific until you run out of items

4) Return a sorted list containing the items in the order they were identified