user972946
user972946

Reputation:

How to use optional arguments in defprotocol?

I want to have a function in my type which takes an optional argument. I have successfully used optional arguments in functions which do not belong to a type, however, I cannot seem to get it working within a protocol and type.

My failed trial:

Clojure 1.4.0
user=> (defprotocol OptArg
(func [this a & b]))
OptArg

user=> (deftype Imp [] OptArg
(func [this a & b] (println a b)))
user.Imp

user=> (func (Imp.) 1 2)
CompilerException java.lang.IllegalArgumentException: No single method: func of interface: user.OptArg found for function: func of protocol: OptArg, compiling:(NO_SOURCE_PATH:5) 

user=> (defn opt-arg [a & b] (println a b))
#'user/opt-arg

user=> (opt-arg 1 2)
1 (2)
nil
user=> (opt-arg 1)
1 nil
nil
user=>

Upvotes: 6

Views: 2655

Answers (2)

Ning Sun
Ning Sun

Reputation: 2191

I made a defprotocol+ for you to define protocol with optional arguments. The idea is to make & args as a fixed argument in protocol and create a wrapper function automatically.

Check out this gist for macro.

Usage

(defprotocol+ IPipeline
  (run-and-wait [this & args]))

(defrecord+ Pipeline []
  IPipeline
  (run-and-wait [this & args]
    ))

(run-and-wait (Pipeline.) 1 2 3 4 5)

Upvotes: 2

bereal
bereal

Reputation: 34272

As answered here, protocols do not support varargs. You have to define a separate method for each required number of arguments or simply accept a list as an argument.

Upvotes: 8

Related Questions