Fork me on GitHub
Liliane Assous11:09:13

Hi, everyone. I’m doing koans 27, and trying to understand how to define a multi that takes 2 args. I keep getting an error - Wrong number of args (2), even though, as far as I can tell, my method is syntactically identical to the even-or-odd method that I took from StackOverflow, which does work:

;; Mine - doesn't work
(def user1 {:name "Elior" :contact-method "sms"})
(def user2 {:name "Lily" :contact-method "email"})
(defn sms-user[user u]
    (str (:name user) "smsing " (:name u))
(defmulti notify-user (fn [user _] (:contact-method user)))
(defmethod notify-user "sms" [a _] (str a _))
(notify-user user1 user2)

;; StackOverflow - works
(defmulti even-or-odd (fn [x _] (even? x)))
(defmethod even-or-odd true [a _] (str a _))
(defmethod even-or-odd false [a _] :odd)
(even-or-odd 2 3)


Works for me.


Are you testing this at the REPL? defmulti doesn't allow you to redefine the dispatch function when it's inline. There's a helpful example here:

👍 1

(notify-user user1 user2)
=> "{:name \"Elior\", :contact-method \"sms\"}{:name \"Lily\", :contact-method \"email\"}"


I suspect as well that what you're seeing is some "dirty" REPL state. You can easily check if this is the case by firing up a new REPL session - you should see the same results as I did when evaluating the code in the new session.

Liliane Assous11:09:45

Thanks, you’re right, it does work in a new REPL. Which begs the question - when does a REPL get “dirty”?

Martin Půda12:09:44

That wasn't REPL issue, but defmulti behaviour mentioned by @UE72GJS7J (my links describe that as well).

Liliane Assous12:09:56

Are there any other functions that behave similarly? When extending protocols, maybe? :thinking_face:

Dane Filipczak13:09:10

@U040HQSN3Q9 protocols don’t display this gotcha. I don’t want to claim that there’s nothing else that behaves this way, but I can’t think of any, and defmulti is the one that predictably causes a lot of pain : )