Closed Kalimehtar closed 11 years ago
Kalimehtar,
Basically the idea in clojure for multimethods was that the programmer gets to define what the dispatch function is exactly. In CLOS, great though it is, still dispatches based on the classes of the arguments, or in the case of the eql specifier, a particular instance of a class.
In the example I gave in the readme, you'll note that the arguments x and y to the 'encounter' function are actually hash tables, and I defined the multimethod dispatch function to do a hash lookup for the :species keyword and compare the values returned.
However, in your eql specifier, the arguments x and y are keyword symbols.
CLOS still does have an advantage over the clojure multimethod approach in that methods are combined into an 'effective' or 'computed' method (and can be controlled with call-next-method and similar), since the dispatch function is confined to the type hierarchy. With multimethods, the dispatch function is completely arbitrary and can't be automatically combined, since there is no hierarchy (although I believe in clojure one can define a hierarchy, but it's not as automatic).
So this was a little project to teach myself some macros and a test to see how hard it was to port a feature from clojure to Common Lisp. It wasn't, naturally. ;)
Does that make sense?
-Matt
I understand now.
It is rather state-machine with several states, than "methods" in CLOS or C++ meaning. Unless I mistaken, this multimethods cannot be partial. You cannot make
(defmultimethod encounter (list :bunny t) (x y)
:bunny-meets alien)
and expect,that
(enconter (alexandria:plist-hash-table '(:species :bunny))
(alexandria:plist-hash-table '(:species :unknown)))
will call it. Then it is exactly state processor. You should enumerate all state-combinations with actions in each.
(defmethod encounter (x (eql :bunny)) (y (eql :lion)) :run-away)