0

With a function that uses keyword arguments using this style of function definition:

(defun some-name (&rest kwargs)
  (plist-get kwargs 'example))

Is there a convenient way to ensure only supported keyword-arguments as passed in?

So a typo in a keyword argument doesn't pass by unnoticed.

2
  • The doc-string for plist-get states in relevant part: "This function never signals an error." Therefore, you will need to set up your own rules prior to the call of plist-get, and also setup your own way to specify an error. If the kwargs argument passes your test, then proceed to the call of plist-get.
    – lawlist
    Commented May 25, 2020 at 9:24
  • Is there some defacto-standard way of detecting this and reporting the unknown key in the plist?
    – ideasman42
    Commented May 25, 2020 at 10:14

2 Answers 2

3

cl-defun handles this usecase:

(require 'cl-lib)
(cl-defun test (&key foo bar)
  (list foo bar))

(test :foo 1 :bar 2) ; (1 2)
(test :foo 1 :bar 2 :baz 3) ; Error: "Keyword argument :baz not one of (:foo :bar)"

In case you want the opposite behavior, pass &allow-other-keys after the key list.

0

This can be done by parsing the keyword arguments directly.

;; Function that takes two optional keyword arguments: `example-a', `example-b'.
(defun some-name (&rest kwargs)
  ;; Two example keywords.
  (let ((example-a-as-var nil)
        (example-b-as-var nil))

  ;; Extract keyword args.
    (let ((kw-iter keyword-args))
      (while kw-iter
        (let ((kw-key (pop kw-iter))
              (kw-val (pop kw-iter)))
          (cond
           ((eq kw-key :example-a) (setq example-a-as-var kw-val))
           ((eq kw-key :example-b) (setq example-b-as-var kw-val))
           (t (error "Unknown keyword argument %S" kw-key))))))
    ;; End argument extraction/validation.

    ;; function body.
    ))
2
  • 1
    Why not use cl-defun?
    – wasamasa
    Commented May 26, 2020 at 7:25
  • I avoid cl-lib because the API has much larger surface area to memorize.
    – ideasman42
    Commented May 26, 2020 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.