Besides the cosmetic differences, what is the difference between key
and optional
these:
(defun play (&key now)
...)
(defun play (&optional now)
...)
As i understand it, in both cases:
- they are optional
- neither returns a list to the function like &rest
CodePudding user response:
When you use optional parameters, you can only omit arguments at the end of the argument list, since they're processed in order. If there are several optional arguments and you want to be selective about which you want to provide, you normally use keyword arguments.
See the built-in functions that use keyword arguments for examples. OPEN
has lots of options, but any particular call will generally only use a couple of them. If it used &optional
and you wanted to provide the last optional argument, you would have to fill in all the preceding arguments with default values.
CodePudding user response:
&optional
Optional arguments are, hmm, optional. You can omit them and they may have default values. They need to be provided in order.
(defun hello-world (&optional (message "Hi there!")
(stream *standard-output*))
(format stream "Hello World: ~a" message)
(finish-output stream))
(hello-world "Good morning!")
Above omits the output stream, since it is optional and has a default value.
(with-output-to-string (stream)
(hello-world "Good morning!" stream))
Above provides a stream, since we don't want to use the default value.
Thus the following three call variations are possible:
(hello-world "Good morning!" stream)
(hello-world "Good morning!")
(hello-world)
&key
Keyword arguments are named, optional and can be provided in any order:
(defun hello-world (&key (message "Hi there!")
(stream *standard-output*))
(format stream "Hello World: ~a" message)
(finish-output stream))
Now all the following five call variations are possible:
(hello-world :message "Good morning!" :stream stream)
(hello-world :stream stream :message "Good morning!")
(hello-world :message "Good morning!")
(hello-world :stream stream)
(hello-world)
One can provide the keyword/value pairs in any order, omit some or omit all.
Benefits of keyword arguments
Thus keyword arguments give a lot of flexibility:
- the developer usually needs not to remember the exact order of arguments
- the developer can provide all, a subset or none of the arguments
- the code gets more self-documenting, since the parameters are named in the function call
The price to pay: keyword arguments may make some calls slower than calls with fixed parameter lists.
When to use keyword parameters?
Developers will write functions, macros, ... with keyword parameters when there are multiple (even many) optional arguments without clear order preference. The more readable code is an added advantages.