Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic function with keyword arguments

I'm a newbie to Clojure and I was wondering if there is a way to define a function that can be called like this:

(strange-adder 1 2 3 :strange true)

That is, a function that can receive a variable number of ints and a keyword argument.

I know that I can define a function with keyword arguments this way:

(defn strange-adder
  [a b c & {:keys [strange]}]
  (println strange)
  (+ a b c))

But now my function can only receive a fixed number of ints.

Is there a way to use both styles at the same time?

like image 253
izaban Avatar asked Aug 26 '13 16:08

izaban


People also ask

How do you use Variadic arguments?

It takes one fixed argument and then any number of arguments can be passed. The variadic function consists of at least one fixed variable and then an ellipsis(…) as the last parameter. This enables access to variadic function arguments. *argN* is the last fixed argument in the variadic function.

Can you pass function with arguments in Python?

A function can take multiple arguments, these arguments can be objects, variables(of same or different data types) and functions.

How do you pass keyword arguments in Python?

In Python, we can pass a variable number of arguments to a function using special symbols. There are two special symbols: *args (Non Keyword Arguments) **kwargs (Keyword Arguments)

How do you call a function with variable number of arguments?

To call a function with a variable number of arguments, simply specify any number of arguments in the function call. An example is the printf function from the C run-time library. The function call must include one argument for each type name declared in the parameter list or the list of argument types.


1 Answers

unfortunately, no.

The & destructuring operator uses everything after it on the argument list so it does not have the ability to handle two diferent sets of variable arity destructuring groups in one form.

one option is to break the function up into several arities. Though this only works if you can arrange it so only one of them is variadic (uses &). A more universal and less convenient solution is to treat the entire argument list as one variadic form, and pick the numbers off the start of it manually.

user> (defn strange-adder
        [& args]
         (let [nums (take-while number? args)
               opts (apply hash-map (drop-while number? args))
               strange (:strange opts)]
          (println strange)
              (apply + nums)))
#'user/strange-adder
user> (strange-adder 1 2 3 4 :strange 4)
4
10
like image 158
Arthur Ulfeldt Avatar answered Nov 16 '22 03:11

Arthur Ulfeldt