Optional arguments of function is a nice feature and many programming language support it. For example in VB.NET

 
Private Sub Foo( ByVal strName as String, _
                 Optional ByVal objRow as DataRow = Nothing , _
                 ByVal bolExist as Boolean)
    ' do stuff

End Sub 
 
Foo("hello",,True)
 

This is how to define optional arguments and its default value in VB.NET. If we put the optional arguments in the end of parameter list.

 
Private Sub Foo( ByVal strName as String, _
                 ByVal bolExist as Boolean, _
                 Optional ByVal objRow as DataRow = Nothing )
    ' do stuff

End Sub 
 
Foo("hello",True)
 

Lets see how Clojure do it. Clojure using a mechanism called destructuring to support binding variable. Both in let binding list and fn parameter list.

For example,

 
(defn testfun [ & {arg1 :arg1key arg2 :arg2key :or {arg1 "defaultarg1" arg2 "defaultarg2"}}] 
  (println (str "value of arg1 is " arg1))
  (println (str "value of arg2 is " arg2))
)
 

The map declares how the function will destructuring the input parameters. The first part is a list of parameter name and their keyword, the :or and the map followed is default value in case the input parameter don't provide data.

You will call it like this

 
(testfun :arg1key 3 :arg2key 4)
value of arg1 is 3
value of arg2 is 4
 

Or using the default value

 
(testfun)
value of arg1 is defaultarg1
value of arg2 is defaultarg2
 

If you don't need a different keyword name, you can use the same keyword name as parameter name.

 
(defn testfun [ & { :keys [arg1 arg2]  :or {arg1 "defaultarg1" arg2 "defaultarg2"}}] 
  (println (str "value of arg1 is " arg1))
  (println (str "value of arg2 is " arg2))
)
 

Now the keyword will be :arg1 and :arg2

 
(testfun :arg1 3 :arg2 4)
(testfun :arg1 2 )