cl-destructuring-bind auf partieller plist?

9

Dies verursacht einen Fehler

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

weil der :cSchlüssel / Wert in der Musterübereinstimmung nicht behandelt wird.

Oft möchte ich eine Teilmenge von Schlüsseln / Werten aus einer Liste extrahieren, bin aber cl-destructuring-bindaufgrund dieser Einschränkung nicht geeignet.

Gibt es eine Möglichkeit, nicht cl-destructuring-bindübereinstimmende Schlüssel im EXPR einfach zu ignorieren? Ich bin mir nicht sicher, wie das offizielle allgemeine Lisp-Verhalten hier aussehen soll. Ist der Fehler in der Spezifikation?

Beachten Sie, dass die Dash-Bibliothek eine ähnliche Destrukturierung unterstützt, für die jedoch ein -letBoilerplate erforderlich ist, um jedem Schlüssel ein Symbol zuzuweisen. Ein Fix wurde vorgeschlagen

Unter Berücksichtigung der Antwort von Stefan funktioniert dies gut:

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

Antworten:

10

Da cl-destructuring-binddie Arglist-Konvention von CommonLisp verwendet wird, sollten Sie in der Lage sein:

(cl-destructuring-bind 
    (&key a b &allow-other-keys) 
    '(:a "foo" :b 13 :c "bar") 
  (list a b))
Stefan
quelle
1
Nicht nur "sollte in der Lage sein". Es funktioniert tatsächlich.
Harald Hanche-Olsen
Ich schrieb einen Makro, um es einfacher zu bedienen
fommil
Ich habe einige seltsame, nicht reproduzierbare Fehler mit diesem Makro erhalten. Ist cl-destructuring-bindbekannt, dass es Probleme gibt? github.com/ensime/ensime-emacs/issues/458
fommil
Ich glaube nicht, dass es bekannte Probleme gibt cl-destructuring-bind(nun, es gibt einige kleinere Probleme, aber keine, die zu falschem Verhalten führen sollten, AFAIK). OTOH Ich bin mir nicht sicher, wie stark es getestet wurde.
Stefan