I want to create a function that takes in a required argument x, and either a optional argument opt1 OR a keyword argument opt2.
Right now I have
(defn foo x & [opt1 {:keys [opt2]}]
...
But the above signature only lets me pass in keyword argument opt2 when both x and opt1 is present like
(foo 'x 'opt1 {:opt2 'opt2})
not like this
(foo 'x {:opt2 'opt2})
Please help me create a function that takes a required argument X and either opt1 or opt2, where opt2 is a keyword argument.
Thank you.
EDIT: I want to do the same for other macros as well. So I still need to use the defmacro.
The problem is ambiguity. Consider a function
(fn foo [x y & args])that takes two optional arguments and then any number of keyword arguments. If you then call it like(foo :bar :baz), how does your program handle it?x=>:bar,y=>:baz? Orxandynot provided, with a single:bar=>:bazkeyword argument?Even in Common Lisp, which has arguably even more flexibility than Clojure in parsing function parameters, mixing optional and keyword arguments is not recommended, according to at least one popular book.
Your best bet is to change all of your arguments to positional arguments, or all of your parameters to keyword arguments. If you use keyword arguments, you can use hash-map destructuring to provide defaults for “optional” keyword parameters.