On Wed, Sep 5, 2012 at 12:31 AM, Brian Marick <mar...@exampler.com> wrote:

> I'm trying to write exercises for multimethods. Book readers will be
> working at the repl. Multimethods are stateful in a bad way, as shown
> below. Is there some sort of trick to using multimethods at the repl, or
> should I just give up on exercises using them?
>
> ;; Two types:
> user=> (defn ship [name] (with-meta {:name name} {:type :ship}))
> user=> (defn asteroid [name] (with-meta {:name name} {:type :asteroid}))
>
> ;; The dispatch function and defmulti
>
> user=> (def classify-colliding-things
>             (fn [thing1 thing2]
>               [(type thing1) (type thing2)]))
> user=> (defmulti collide classify-colliding-things)
>
> ;; Actually, since the arguments can come in any order, it'd be better to
> sort the types:
>
> user=> (def classify-colliding-things
>             (fn [thing1 thing2]
>               (sort [(type thing1) (type thing2)])))
>
> ;; And let's redefine the multimethod to use the new comparison function.
>
> user=> (defmulti collide classify-colliding-things)
>
> ;; OK, now we define the methods.
>
> user=> (defmethod collide [:asteroid :ship]
>          [& things]
>          "collide asteroid to ship")
>
> ;;; And use them with great confidence:
>
> user=> (collide (ship "Space Beagle") (asteroid "Malse"))
> IllegalArgumentException No method in multimethod 'collide' for dispatch
> value: [:ship :asteroid]  clojure.lang.MultiFn.getFn (MultiFn.java:121)
>
> ;;; The redefinition didn't take
>

here is a hack: define a var with the multimethod name:

user> (def collide nil)
; #'user/collide
user>  (defmulti collide classify-colliding-things)
; #'user/collide
user> (defmethod collide [:asteroid :ship]
        [& things]
        "collide asteroid to ship")
; #<MultiFn clojure.lang.MultiFn@9fe5c5>
user>  (collide (ship "Space Beagle") (asteroid "Malse"))
; "collide asteroid to ship"



When writting multimethod I always preceed their definitions like this:

; remove existing definition
(def mymulti nil)
(defmulti mymulti ...)


Also, I "heard" that this problem don't exists in nRepl (?)

Denis





> -----
> Brian Marick, Artisanal Labrador
> Contract programming in Ruby and Clojure
> Occasional consulting on Agile
> Writing /Functional Programming for the Object-Oriented Programmer/:
> https://leanpub.com/fp-oo
>
>
> --
> 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
> Note that posts from new members are moderated - please be patient with
> your first post.
> 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
>

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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