Re: Nested Multimethods

2008-10-14 Thread Rich Hickey

On Mon, Oct 13, 2008 at 11:14 PM, Stuart Halloway
[EMAIL PROTECTED] wrote:

 Hi Patrick,

 How about:

 (defmulti length (fn [x]
  (if (= :stateMachine  (:class x))
(:state x)
(:class x

 (defmethod length :yardstick [x] 36)
 (defmethod length :walking [x] short)
 (defmethod length :running [x] long)

 user= (length {:class :yardstick})
 36
 user= (length {:class :stateMachine :state :walking})
 short
 user= (length {:class :stateMachine :state :running})
 long

 It would probably be better to have the fn return a vector so you
 don't have to worry about :state and :class values with colliding
 names, but that's the basic idea.


In general, if you have a conditional or other enumeration of things
in your dispatch method it is a warning sign that you might not be
getting the leverage out of multimethods - their prime reason to exist
is to provide open, extensible case logic.

Never say never, but in this case it's better to use two multimethods.

Rich

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Nested Multimethods

2008-10-14 Thread Rich Hickey



On Oct 13, 11:01 pm, CuppoJava [EMAIL PROTECTED] wrote:
 Is there anyway to do the following with the existing multi-method
 facilities?

 There is a general multi-method length(object) that splits off to
 different methods depending on the :class of the object.

 And then specifically for objects with :class = :stateMachine, I want
 to define it's method to split off further depending on the :state of
 the object.

 (defmulti length :class)
 (defmethod-multi length :stateMachine :state)

 (defmethod length :stateMachine :walking
   (println Short distance))

 (defmethod length :stateMachine :running
   (println Long distance))


The answer is right in your title - use more than one multimethod and
nest them:

(defmulti length :class)
(defmulti sm-length :state)

(defmethod length :stateMachine [x]
  (sm-length x))

(defmethod sm-length :walking [_]
  (println Short distance))

(defmethod sm-length :running [_]
  (println Long distance))

(length {:class :stateMachine :state :running})
- Long distance

Rich

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Nested Multimethods

2008-10-14 Thread mb

Hello,

On 14 Okt., 16:58, Randall R Schulz [EMAIL PROTECTED] wrote:
 I have heard it claimed (on one of the Scala lists, I think)
 that patterns themselves are an anti-pattern...

I think there are always patterns. They are just different. In
Clojure there is maybe the Driver Function pattern: Instead
of writing a huge macro, put the logic in a driver function,
package up the arguments in (fn [] ...) closures and pass
them to the driver.

Sincerely
Meikel


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Nested Multimethods

2008-10-13 Thread Stuart Halloway

Hi Patrick,

How about:

(defmulti length (fn [x]
  (if (= :stateMachine  (:class x))
(:state x)
(:class x

(defmethod length :yardstick [x] 36)
(defmethod length :walking [x] short)
(defmethod length :running [x] long)

user= (length {:class :yardstick})
36
user= (length {:class :stateMachine :state :walking})
short
user= (length {:class :stateMachine :state :running})
long

It would probably be better to have the fn return a vector so you  
don't have to worry about :state and :class values with colliding  
names, but that's the basic idea.

Cheers,
Stuart

 Is there anyway to do the following with the existing multi-method
 facilities?

 There is a general multi-method length(object) that splits off to
 different methods depending on the :class of the object.

 And then specifically for objects with :class = :stateMachine, I want
 to define it's method to split off further depending on the :state of
 the object.

 (defmulti length :class)
 (defmethod-multi length :stateMachine :state)

 (defmethod length :stateMachine :walking
  (println Short distance))

 (defmethod length :stateMachine :running
  (println Long distance))

 Thanks very much for your help.
  -Patrick
 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---