Protocols don't support varargs. You've defined a protocol with two
methods named say: one takes one argument named a, the other takes
three arguments named a, &, and b.
Protocols are for describing a very minimal set of functionality
needed to implement some richer feature set; the idea is that you
define a Say protocol that is capable of saying things in some basic
sense, and then build a library of functions that operate on Sayable
objects, providing the nice syntactical sugar in the library of real
functions, not in the protocol itself. If you want a say function that
behaves totally differently depending on how many arguments it's
passed (which seems kinda silly, but I'll assume that it's a contrived
example), you could do something more like this:
(defprotocol Say
(say [this args]))
(defrecord Robot []
Say
(say [this args]
(let [[a & [b]] args]
(println (or b (str "hello, " a))))))
(defn make-something-talk [obj & args]
(say obj args))