9

This causes an error

(cl-destructuring-bind 
    (&key a b) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b)) 

because the :c key/value is not handled in the pattern match.

Often I find myself wanting to extract some subset of keys/values from a plist, but cl-destructuring-bind isn't appropriate because of this limitation.

Is there a way to make cl-destructuring-bind simply ignore unmatched keys in the EXPR? I'm not sure what the official common lisp behaviour is supposed to be here, is the error in the spec?

Note that the dash library has some support for a similar destructuring with -let, but that requires some boilerplate to assign a symbol to each key. A fix has been proposed

Taking Stefan's answer into account, this works well:

(defmacro plist-bind (args expr &rest body)
  "`destructuring-bind' without the boilerplate for plists."
  `(cl-destructuring-bind
       (&key ,@args &allow-other-keys)
       ,expr
     ,@body))

(plist-bind
  (a b)
 '(:a "foo" :b 13 :c "bar")
 (list a b)) => ("foo" 13)
10

Since cl-destructuring-bind uses CommonLisp's arglist convention, you should be able to do:

(cl-destructuring-bind 
    (&key a b &allow-other-keys) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b))
4
  • 1
    Not merely “should be able to”. It actually does work. – Harald Hanche-Olsen May 26 '16 at 6:19
  • I wrote a macro to make it easier to use – fommil May 28 '16 at 15:46
  • I've been getting some strange non-reproducible errors with this macro, is cl-destructuring-bind known to have any problems? github.com/ensime/ensime-emacs/issues/458 – fommil Jun 1 '16 at 21:55
  • I don't think there are known problems in cl-destructuring-bind (well, there are some minor issues but none that should lead to incorrect behavior, AFAIK). OTOH I'm not sure how heavily it's been tested. – Stefan Jun 2 '16 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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