cl-destructuring-bind em plist parcial?

9

Isso causa um erro

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

porque a :cchave / valor não é tratada na correspondência de padrões.

Freqüentemente me vejo querendo extrair algum subconjunto de chaves / valores de uma lista, mas cl-destructuring-bindnão é apropriado por causa dessa limitação.

Existe uma maneira de cl-destructuring-bindsimplesmente ignorar chaves sem correspondência no EXPR? Não sei ao certo qual deveria ser o comportamento oficial do cisco comum aqui, é o erro nas especificações?

Observe que a biblioteca de traços tem algum suporte para uma desestruturação semelhante com -let, mas isso requer alguns clichês para atribuir um símbolo a cada tecla. Uma correção foi proposta

Levando em conta a resposta de Stefan, isso funciona bem:

(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
fonte

Respostas:

10

Como cl-destructuring-bindusa a convenção de arglist do CommonLisp, você deve ser capaz de:

(cl-destructuring-bind 
    (&key a b &allow-other-keys) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b))
Stefan
fonte
11
Não apenas "deve ser capaz de". Realmente funciona.
Harald Hanche-Olsen
Eu escrevi uma macro para torná-lo mais fácil de usar
fommil
Estou recebendo alguns erros estranhos não reproduzíveis com essa macro, cl-destructuring-bindsabe-se que tem algum problema? github.com/ensime/ensime-emacs/issues/458
fommil
Acho que não há problemas conhecidos cl-destructuring-bind(bem, existem alguns problemas menores, mas nenhum que deva levar a um comportamento incorreto, AFAIK). OTOH Não sei ao certo o quanto foi testado.
Stefan