Over a million developers have joined DZone.

Named Parameters for Clojure

DZone's Guide to

Named Parameters for Clojure

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

Clojure can simulate named parameters, or a mix of positional and named parameters. This is really old news, dating back to Clojure 1.2 if evidence serves, but I always have trouble finding this exact syntax, and it is not fully obvious.

Say you want to accept a certain number of optional parameters with names, and perhaps, defaults. It turns out you can combine rest parameters (the ones that come after a &) with map destructuring.

In the simple case, you don't care what the possible options are, and you don't have any defaults.

(defn named-parameters
  [& {:as params}]
The keys and values you pass to this function, say  (named-parameters :foo 1 :bar 2) , are collected together as symbol  params .
If you don't provide an even number of values (that is, the same number of keys and values), you'll get a reasonable exception, such as  java.lang.IllegalArgumentException: No value supplied for key: :bar

Easy-peasey ... but you need to extract values from the params map to use them inside the function, e.g.: (:foo params). It would be nicer to have them as symbols, just like with normal positional parameters. This is also easy, by leveraging more of the features of map destructuring:

(defn named-params 
  [& {:keys [foo bar] 
    :or {foo "foo-default" bar "bar-default"}}] 
    {:output-foo foo :output-bar bar})
The  :keys  identifies the keywords expected in the map; it works backwards from the symbol name,  foo , to the expected keyword,  :foo .
There's also a  :syms (for when the keys are expected to be symbols) and  :strs (for when the keys are expected to be strings).

The :or identifies default values for each symbol. The end result is that we can rely on defaults from :or or provide our own values when invoking the function:

(named-params :bar "override-bar") 
==> {:output-foo "foo-default", :output-bar "override-bar"}
And since this is Clojure, you can combine all of these things together quite easily ... some positional parameters, some named, some identified by keywords, others identified by symbols.

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.


Published at DZone with permission of Howard Lewis Ship, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}