cl-destructuring-bind sur plist partiel?

9

Cela provoque une erreur

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

car la :cclé / valeur n'est pas gérée dans la correspondance de modèle.

Souvent, je me retrouve à vouloir extraire un sous-ensemble de clés / valeurs d'un plist, mais ce cl-destructuring-bindn'est pas approprié en raison de cette limitation.

Existe-t-il un moyen de cl-destructuring-bindsimplement ignorer les clés sans correspondance dans l'EXPR? Je ne sais pas quel est le comportement officiel de lisp commun censé être ici, est-ce l'erreur dans la spécification?

Notez que la bibliothèque de tirets prend en charge une déstructuration similaire avec -let, mais cela nécessite un passe-partout pour attribuer un symbole à chaque clé. Un correctif a été proposé

Compte tenu de la réponse de Stefan, cela fonctionne bien:

(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)
fommil
la source

Réponses:

10

Puisque cl-destructuring-bindutilise la convention d'arglist de CommonLisp, vous devriez pouvoir faire:

(cl-destructuring-bind 
    (&key a b &allow-other-keys) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b))
Stefan
la source
1
Pas seulement «devrait pouvoir». Cela fonctionne réellement.
Harald Hanche-Olsen
J'ai écrit une macro pour en faciliter l'utilisation
fommil
J'ai eu des erreurs étranges non reproductibles avec cette macro, est cl-destructuring-bindconnu pour avoir des problèmes? github.com/ensime/ensime-emacs/issues/458
fommil
Je ne pense pas qu'il y ait de problèmes connus dans cl-destructuring-bind(enfin, il y a quelques problèmes mineurs mais aucun qui devrait conduire à un comportement incorrect, AFAIK). OTOH Je ne sais pas à quel point il a été testé.
Stefan