There is no standard way to do this in CL. You can force the function to take everything in the rest parameter and independently analyze the keyword arguments if you do not want to develop the API in different ways.
However, here are a few points for further research. They may be useful in specific use cases, but are quite limited and use implementation-specific behavior.
You can use &allow-other-keys in the lambda list or :allow-other-keys t when calling foo to prevent an unknown key error, but rest will also include the keys and values ββof your keyword arguments:
CL-USER> (defun foo (&rest rest &key (a 1) (b 2)) (list rest ab)) FOO CL-USER> (foo) (NIL 1 2) CL-USER> (foo :a 100 12 3 :allow-other-keys t) ((:A 100 12 3 :ALLOW-OTHER-KEYS T) 100 2) CL-USER> (defun foo (&rest rest &key (a 1) (b 2) &allow-other-keys) (list rest ab)) FOO CL-USER> (foo) (NIL 1 2) CL-USER> (foo :a 100 12 3) ((:A 100 12 3) 100 2)
As correctly indicated in the comment below, this may signal an error. It works for me in CLISP, SBCL, and CCL according to the default optimization settings, but by standard the keyword argument names (i.e. the first of each pair of arguments) must be characters. Regardless of whether it works, it depends on the level of security and depends on the implementation. It should signal an error (about the corresponding implementations) in the secure code (security level 3).
In general, using other keys may be useful for passing keyword arguments, but this is not quite what you wanted. One quick and dirty way is to filter the parameters of keywords in rest and simply discard them and their subsequent elements. Something like that:
CL-USER> (defun foo (&rest rest &key (a 1) (b 2) &allow-other-keys) (let ((rest (loop for (key value) on rest by
Which, alas, the standard will only work for an even number of arguments, as his answer indicates. (It may work with an odd number of arguments in some implementations for some security levels, but it did not work in the tested versions.) In addition, it is obvious that it is not reliable in other ways (different positions of keyword arguments, etc.) , and not for use in production, but as a starting point for possible research.
The correct solution should be to write your own argument parser for the arguments and use it with rest or, as stated in the coredump answer, using another API. Another point worth mentioning is that in CL apply large number of arguments is usually not a good idea, as this can lead to inefficient code. To make matters worse, it is also not very reliable, since the number of allowed arguments depends on the implementation. For example, under CCL in my system, call-arguments-limit is 65536. This can be significant - even an order of magnitude more - less with other implementations and systems. Therefore, generally speaking, prefer reduce ing apply large number of arguments.