Clojure – Multi-Arity and Variadic functions

Yan Cui

I help clients go faster for less using serverless technologies.

In F#, you can’t overload a let-bound function, and whilst it’s a hindrance sometimes you can generally work around it easily enough since you can still overload members of a class. All you need to do is to wrap the module and constituent functions into a class and overload the class members instead.

Multi-Arity Functions

This is where multi-arity functions come in in Clojure (an arity is simply the number of arguments that a function can take).

One way to define multi-arity functions is to use the defn macro, for instance:

As you’ve probably noticed, it’s possible for one overload to call another, so you can use this technique to set default argument values as shown above. On its own, that’s not very interesting, and an effect that can be easily replicated in F# using a combination of optional parameters and the built-in defaultArg function with class members, even without resorting to overloading (again, this is sadly only supported with class members and not functions..).

Variadic Functions

What is definitely more interesting is Clojure’s support for variadic functions – functions with infinite arity.

A variadic function has a & symbol in its arguments list, which tells the compiler that the next parameter collects all remaining arguments as a sequence. So, if we rewrite the greet function to take one or more arguments we can end up with a variadic function such as:

As you can see, the arguments “Darryl”, “Deepu” and “Tom” has been packed into the argument rest in the function definition and printed as a list (Clojure’s lists are enclosed in parentheses ( ) just like its function invocations). If you come from a .Net background then this behaviour should be familiar to you, because that is how parameter arrays works in .Net.

So what’s so special about variadic functions in Clojure then?

To quote Sebastian Shaw from the excellent X-Men First Class film:

image

In Clojure, there’s a built-in apply function which allows you to ‘unpack’ a sequence and pass the unpacked values to a function as individual arguments. With this, we can now rewrite the variadic version of greet as follows:

Notice that the arguments “Darryl”, “Deepu” and “Tom” are no longer treated as a list but as individual arguments to the print function, pretty neat. This SO answer also sheds some more light on why variadic functions exist in Clojure with some interesting examples and idiomatic use of this type of functions.

 

Links

MSDN – F# Parameters and Arguments

Clojure – Functional Programming

Clojure Docs – apply

SO – Why are many Clojure functions variadic

Clojure Cheatsheet

Learn X in Y minutes – where X = Clojure


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


Leave a Comment

Your email address will not be published. Required fields are marked *