Binding keyword arguments

By default, keyword argument variable bindings match the name of the keyword used to pass the value. For example:

(defun keytest (&key foo)
  (list foo))

* (keytest :foo 42)
=> (42)

However, the variable doesn’t have to match the keyword provided. The following syntax will accept a keyword of :foo in the function call but bind a variable named bar:

(defun keytest (&key ((:foo bar)))
  (list bar))

* (keytest :foo 42)
=> (42)

Binding keywords this way can be helpful when binding a plist via destructuring-bind when you don’t want the plist keys to name the variables you actually want to use in the scope of the destructuring bind. For example, the plist may contain (:customer-id 42 ...), but in your context it makes more sense to bind a variable named old-customer-id.

The “keyword” also need not be a keyword:

(defun keytest (&key ((foo bar)))
  (list bar))

* (keytest 'foo 42)
=> (42)

Using internal symbols as function keyword arguments is one way to indicate that they are not part of a function’s public API.