I want to use both &rest
and &key
at the same time. However, the attempted code below:
(defun test (&rest args &key (name "who")) nil)
(test 1 2 3 4 5 :name "hoge")
causes an error:
*** - TEST: keyword arguments in (1 2 3 4 5 :NAME "hoge") should occur pairwise
and when I gives only keyword parameter like (test :name "hoge")
, it works. Is it possible to use both &rest and &key?
Use a semicolon to join two related independent clauses in place of a comma and a coordinating conjunction (and, but, or, nor, for, so, yet). Make sure when you use the semicolon that the connection between the two independent clauses is clear without the coordinating conjunction.
A semicolon may be used between independent clauses joined by a connector, such as and, but, or, nor, etc., when one or more commas appear in the first clause. Example: When I finish here, and I will soon, I'll be glad to help you; and that is a promise I will keep.
When to Use a Semicolon. A semicolon (;) is a punctuation mark that has two main functions: Semicolons separate items in a complex list. For example, The Council is comprised of ten members: three from Sydney, Australia; four from Auckland, New Zealand; two from Suva, Fiji; and one from Honiara, Solomon Islands.
The primary use of semicolons is to join two main clauses. The difference between semicolons and colons is that colons can combine two independent clauses, but their primary use is to join independent clauses with a list or a noun.
The combination of &key
and
&rest
are actually very
common in Common Lisp, but almost always together with
&allow-other-keys
.
E.g., suppose you want to define a wrapper for
write
but do not want to list
explicitly all the keyword arguments it takes:
(defun my-write (object &rest args &key stream &allow-other-keys)
(write "my wrapper" :stream stream)
(apply #'write object args))
You will find many places where this
&rest
/&key
/&allow-other-keys
patterns is used wherever the CLOS is actually
implemented.
It's generally not a good idea to mix rest parameters with keyword parameters within a function definition in Common Lisp. If you do so, you should probably consider rewriting the function definition because it can lead to some unexpected behavior. If both &rest and &key appear in a parameter list, then both things happen--all the remaining values, which include the keywords themselves, are gathered into a list that's bound to the &rest parameter, and the appropriate values are also bound to the &key parameters. So the (name "who") keyword parameter is bound to your list of rest parameters by default. if you try to enter the arguments (1 2 3 4 5), you will get an error because they aren't bound to your parameter (name "who"). Here is an example:
(defun test (&rest args &key (name "who"))
(list args name))
Here we have your function definition. If we try to call the function which return a list of the arguments, we will see that the &rest parameters are bound to they &key parameters here:
CL-USER> (test :name "Davis")
((:NAME "Davis") "Davis")
By mixing &rest parameters and keyword parameters in the same parameter list, you won't be able to enter any rest parameters that don't match your keyword parameter which is why you enter into a breakloop here.
Now, if you want to create a macro, you can technically use multiple parameter lists within the definition, and add keyword parameters in one list, and &rest (or &body) parameters in the other list:
(defmacro hack-test ((&key (name "who")) &body body)
`(list ,name ,@body))
CL-USER> (hack-test (:name "Ricky")
(+ 2 3))
("Ricky" 5)
CL-USER> (hack-test ()
(+ 2 4)
(+ 4 5)
(+ 9 9))
("who" 6 9 18)
CL-USER>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With